-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
Restricted Elasticsearch Clients #81237
Comments
Pinging @elastic/kibana-security (Team:Security) |
Pinging @elastic/kibana-platform (Team:Platform) |
We could eventually restrict some client API calls to be restricted to be only performed by core (even if it would be a mess honestly, as we decided to expose a plain/vanilla client instead of a wrapper). However here, you would need to basically only have the |
I was intentionally not proposing solutions just yet, because I didn't want to pigeonhole the discussion. I do have one idea, but I'm not sure how feasible it is:
Yeah I'm not too keen on a wrapper either. I really like the idea of exposing the plain client. Could we create the plain client without specific endpoints? If so, then each plugin could get a restricted version of the client by default, unless they've indicated that they need access to some privileged endpoints. We could add an optional {
"id": "security",
"version": "8.0.0",
"kibanaVersion": "kibana",
"configPath": ["xpack", "security"],
"requiredPlugins": ["data", "features", "licensing", "taskManager", "securityOss"],
"optionalPlugins": ["home", "management", "usageCollection"],
"server": true,
"ui": true,
"requiredBundles": [],
"entitlements": [{
"elasticsearchClient": {
"privilegedEndpoints": ["security.getUser"]
}
}]
} |
💯 I really hope we can go with a declarative approach using |
It makes an audit harder, but it gives plugins flexibility to implement an additional logic (such as rely on config values, for example) and adds type safety for further changes.
I'm not sure how we can implement it without a wrapper because the |
Those endpoints are still TBD. In general we wouldn't expect other plugins to use a vast majority of the
I don't have a great solution for this just yet, unless we could upstream a change to allow "partial" clients to be created. |
Because the system indices Elasticsearch plugin will only expose a subset of API's it would be nice if the dedicated system indices client only had the types for those API's #82716 Perhaps we can just exclude the sensitive APIs from the internal user client? Relying on Typescript is not a strong control, but if a developer tries to make an API call which results in a TS error it's a very strong signal that they are doing something wrong. |
For system indices, the subset of ES APIs we want to use/allow is known and static, so we could use the same approach we did for the saved object 'retry' client, using composition on the base
We could also, as suggested by @rudolf, just expose a limited ts type, while still providing a 'full' client as the implementation. As the ES call would fails anyway, only having TS as guard control seems good enough to me. For restricted client, I'm not sure of the feasibility, as using the same approach would constraint us to only have statically defined lists of allowed endpoint, which is not what "entitlements": [{
"elasticsearchClient": {
"privilegedEndpoints": ["security.getUser"]
}
}] is suggesting. In the case we would really want that kind of manifest-based permissions, the best we could do would be to expose the whole client type, and throw errors when invoking forbidden apis. This still requires a wrapper of some kind around the |
Background
Kibana's authorization model relies on making certain requests to Elasticsearch as the
kibana_system
user, on behalf of the end user.For example, accessing a dashboard roughly looks like:
Securing access to saved objects happens mostly transparently to engineers. They'd have to go out of their way to access saved objects in a way which bypasses security controls.
Problem
Say for example that I want to retrieve a list of all users within the native realm via the
/_security/users
ES API. If I were to grant thekibana_system
user access to this endpoint, then I could make this information available to Kibana users, even if they themselves didn't have the proper ES privileges. We can instead leverage the kibana privilege model to authorize the end user according to our own rules before making the request askibana_system
on their behalf.This is all possible today, but it doesn't prevent engineers from mistakenly bypassing Kibana's authorization checks. It's entirely possible for another plugin to get an instance of the
ElasticsearchClient
scoped to the internal user, and then make any request they'd like. In doing so, they would bypass our authorization checks, audit logging, etc. The new client has great TS support, but I fear that makes the available options even more discoverable, and engineers might not know that they shouldn't be interacting with some of these endpoints directly.This isn't a problem yet, but I think it would improve the dx and help keep Kibana secure if we could restrict which endpoints plugins could call from the
ElasticsearchClient
exposed by core. In this example above, I wouldn't want other plugins to be able to callclient.security.getUser()
directly. I would instead want to force them to consume the security plugin's public contract in order to call our version, where we can intercept the call, perform the necessary authorization & audit logging, and only then return the response.The text was updated successfully, but these errors were encountered: