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

Check for ml privilege when using the Inference Aggregation #59530

Merged
merged 5 commits into from
Jul 14, 2020

Conversation

davidkyle
Copy link
Member

@davidkyle davidkyle commented Jul 14, 2020

Before running the inference pipeline aggregation check the user has permission to access the Get trained models endpoint (_ml/inference/)

If the user does not have sufficient privilege a security_exception is thrown with the message user [dave] is not an ml user and does not have sufficient privilege to use ml inference. Any suggestions for an alternative message are welcome.

Non issue as the change comes under #58193

@davidkyle davidkyle added :ml Machine learning v8.0.0 v7.9.0 labels Jul 14, 2020
@elasticmachine
Copy link
Collaborator

Pinging @elastic/ml-core (:ml)

@davidkyle
Copy link
Member Author

ping @szabosteve this change adds a security permission check to the inference pipeline. Where should this be documented?

@szabosteve
Copy link
Contributor

@davidkyle Thanks for pinging. I'll add this info to the inference pipeline docs and add you as a reviewer.

final String username = securityContext.getUser().principal();
final HasPrivilegesRequest privRequest = new HasPrivilegesRequest();
privRequest.username(username);
privRequest.clusterPrivileges("manage_ml", "monitor_ml");
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this stop really high privilege users from using inference? For example, the actions permitted by manage_ml are a subset of those permitted by manage (which means manage everything except security), but literally checking for manage_ml might not return true for a user who has manage. I may be wrong as I haven't tested it, but it seems likely that the security code will resolve high level cluster privilege names to sets of actions they allow, but not to other high level cluster privilege names.

You could check for just GetTrainedModelsAction.NAME here instead to solve that potential problem and also make the later code simpler as you'll only be testing for one privilege:

Suggested change
privRequest.clusterPrivileges("manage_ml", "monitor_ml");
privRequest.clusterPrivileges(GetTrainedModelsAction.NAME);

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes that works

Comment on lines 233 to 234
"user [" + username + "] is not an ml user and does not have sufficient privilege " +
"to use ml inference"));
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"user [" + username + "] is not an ml user and does not have sufficient privilege " +
"to use ml inference"));
"user [" + username + "] does not have the privilege to get trained models " +
"so cannot use ml inference"));

});
return new InferencePipelineAggregationBuilder(name, bucketPathMap, loadedModel::get, modelId, inferenceConfig, licenseState);
}

static boolean hasMlPrivilege(HasPrivilegesResponse privilegesResponse) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This method won't be needed if just checking one privilege.

context.registerAsyncAction((client, listener) -> {
if (licenseState.isSecurityEnabled()) {
// check the user has ml privileges
SecurityContext securityContext =new SecurityContext(Settings.EMPTY, client.threadPool().getThreadContext());
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: space after equals

SetOnce<LocalModel> loadedModel = new SetOnce<>();
context.registerAsyncAction((client, listener) -> {
BiConsumer<Client, ActionListener<?>> modelLoadAction = (client, listener) ->
Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, nice! That's what to use when in need to return more than a single thing. I'll use that onwards!

final HasPrivilegesRequest privRequest = new HasPrivilegesRequest();
privRequest.username(username);
privRequest.clusterPrivileges(GetTrainedModelsAction.NAME);
privRequest.indexPrivileges(new RoleDescriptor.IndicesPrivileges[]{});
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to set index and application privileges even though they're empty?

Copy link
Member Author

Choose a reason for hiding this comment

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

@SuppressWarnings("unchecked")
static boolean containsKey(String key, Map<String, Object> mapOfMaps) {
Set<String> keys = mapOfMaps.keySet();
for (String keyEntry : keys) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't this the same as doing if (mapOfMaps.contains(key)) return true; ?

Copy link
Member Author

Choose a reason for hiding this comment

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

Ha yeah that might be a simpler way of doing it

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

Copy link
Contributor

@dimitris-athanasiou dimitris-athanasiou left a comment

Choose a reason for hiding this comment

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

LGTM

@davidkyle
Copy link
Member Author

run elasticsearch-ci/packaging-sample-windows

@davidkyle davidkyle merged commit 292f207 into elastic:master Jul 14, 2020
@davidkyle davidkyle deleted the has-priv branch July 14, 2020 19:12
davidkyle added a commit that referenced this pull request Jul 14, 2020
…59562)

The inference pipeline aggregation requires the user has permission to access
the ml get trained models endpoint (_ml/inference/)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants