Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Transform] Secondary credentials used with transforms should only require source and destination index privileges, not transform privileges #94420

Merged
merged 12 commits into from
Mar 10, 2023

Conversation

przemekwitek
Copy link
Contributor

@przemekwitek przemekwitek commented Mar 9, 2023

The internal _validate action was called by PUT action using secondary headers only. This was causing authorization issues if the API key (secondary header) was lacking transform_admin role.
This PR fixes this by providing all the security headers to _validate action using ClientHelper.executeWithHeadersAsync helper method rather than raw client.execute.

Relates #93259

@przemekwitek przemekwitek added >bug and removed WIP labels Mar 9, 2023
@przemekwitek przemekwitek marked this pull request as ready for review March 9, 2023 13:08
@przemekwitek przemekwitek added the :ml/Transform Transform label Mar 9, 2023
@elasticsearchmachine elasticsearchmachine added the Team:ML Meta label for the ML team label Mar 9, 2023
@elasticsearchmachine
Copy link
Collaborator

Hi @przemekwitek, I've created a changelog YAML for you.

@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/ml-core (Team:ML)

// <2> Validate source and destination indices
ActionListener<Void> checkPrivilegesListener = ActionListener.wrap(
aVoid -> ClientHelper.executeWithHeadersAsync(
config.getHeaders(),
Copy link
Contributor

@droberts195 droberts195 Mar 9, 2023

Choose a reason for hiding this comment

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

I find it surprising that this works. config.setHeaders was called inside a block that switched to secondary headers. So I would have thought that here we end up calling ValidateTransformAction using the secondary headers, which should fail if those secondary headers only allow index access and not transform administration.

I can see you have a test that seems to test that this functionality works, but please can you do some extra due diligence on whether this is really working as expected, perhaps by running the test locally with extra debug, or by manually testing it with gradle run.

If this extra testing shows that the existing test is only succeeding by some fluke then I think the way to fix it would be to put this call back to how it was before, and instead switch to secondary headers (using useSecondaryAuthIfAvailable) within the subsections of TransportValidateTransformAction that access the source or destination indices.

If the code really does work correctly as you've got it now then I need to adjust my understanding of what executeWithHeadersAsync does.

Copy link
Contributor Author

@przemekwitek przemekwitek Mar 9, 2023

Choose a reason for hiding this comment

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

So I would have thought that here we end up calling ValidateTransformAction using the secondary headers, which should fail if those secondary headers only allow index access and not transform administration.

Yes, that was indeed the case and the scenario from Quynh I reproduced.

I can see you have a test that seems to test that this functionality works, but please can you do some extra due diligence on whether this is really working as expected, perhaps by running the test locally with extra debug, or by manually testing it with gradle run.

So, I did a little back and forth on this PR and the version you reviewed probably had the test (my new test written exactly for this case) failing in the CI which I noticed and fixed a few hours later...

The reason for this was I noticed Ben's work (#86757) solving the issue #86731 (Prefer secondary authentication headers when creating/updating transforms) and I wanted to keep his tests passing as well.

I ended up with the following (this PR is now updated):

  • pass all the security headers to _validate call
  • only store secondary headers in the transform config.

This way _validate call can be executed even if the secondary headers does not have transform_admin.
And at the same time we only store secondary header in the config in order to use it for data access later on (e.g: creating destination index).

I've just udpated this PR description to reflect the change: now all the security headers are passed on to _validate.

@elasticsearchmachine
Copy link
Collaborator

Hi @przemekwitek, I've created a changelog YAML for you.

@przemekwitek
Copy link
Contributor Author

Some tests are now failing on CI.
So it seems this PR needs more work. I'll update it once it's ready for review again.

@przemekwitek
Copy link
Contributor Author

Some tests are now failing on CI. So it seems this PR needs more work. I'll update it once it's ready for review again.

Ok, the tests are fixed. It was a simple NPE causing these failures.
PR is ready for review again.

Copy link
Contributor

@droberts195 droberts195 left a comment

Choose a reason for hiding this comment

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

Unfortunately I still think there is a problem.

I think the solution is to call _validate using the internal _xpack user, as it's entirely an internal endpoint.

Then, in TransportValidateTransformAction the functions that use a Client should switch to the appropriate headers instead of relying on the caller of _validate to have done this. As far as I can see that's:

function.deduceMappings(client, config.getSource(), deduceMappingsListener);

and:
function.validateQuery(client, config.getSource(), request.timeout(), validateQueryListener);

@przemekwitek przemekwitek changed the title [Transform] Provide security headers when calling _validate [Transform] Secondary credentials used with transforms should only require source and destination index privileges, not transform privileges Mar 10, 2023
@przemekwitek
Copy link
Contributor Author

Unfortunately I still think there is a problem.

I think the solution is to call _validate using the internal _xpack user, as it's entirely an internal endpoint.

Done.

Then, in TransportValidateTransformAction the functions that use a Client should switch to the appropriate headers instead of relying on the caller of _validate to have done this. As far as I can see that's:

function.deduceMappings(client, config.getSource(), deduceMappingsListener);

and:

function.validateQuery(client, config.getSource(), request.timeout(), validateQueryListener);

Done.
I call these actions using executeWithHeadersAsync and provide headers stored in the config (config.getHeaders()).

Copy link
Contributor

@droberts195 droberts195 left a comment

Choose a reason for hiding this comment

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

LGTM if you could just rename a method as per #94420 (comment) before merging.

@przemekwitek przemekwitek merged commit 640c326 into elastic:main Mar 10, 2023
@przemekwitek przemekwitek deleted the call_validate_with_sec_auth branch March 10, 2023 18:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
>bug :ml/Transform Transform Team:ML Meta label for the ML team v8.8.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants