-
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
Add support for secondary auth to Core's ES client #179458
Comments
Pinging @elastic/kibana-core (Team:Core) |
Pinging @elastic/kibana-security (Team:Security) |
Yeah... tbh, I'm not sure how I feel about changing our Would someone (@azasypkin maybe?) mind providing some context on what that |
The ES api (get index count and size in serverless) we are going to access leverages secondary authentication to allow work to be done as a normal user (secondary auth) but passes the operator only REST API check (primary auth). This would allow the API to remain internal but the data/permissions to be representative of the non-operator user's sets of permission. This approach requires Kibana to make a call using 2 valid credentials (one of which is an operator, the other is users token credential.) More details about the API Here ML & Fleet has a similar use case: Currently, the way they implement this is via Downside of this workaround: Using user credentials in this manner also has some drawbacks. For instance, if the bearer token expires after you've extracted it from the request object, Kibana won't attempt to transparently refresh it and retry the request, as it does when you use asCurrentUser. If you forward such a response directly to the "interactive" user (browser), they will be logged out. If not, you might have to retry the request manually somehow. It's not a very common scenario, but it does occur with SAML from time to time. Given that this method will be used for more and more use cases in the future, it would make sense to add a third "scoping" method to the Kibana Elasticsearch client, such as asXXXSecondary. So that you don't have to handle the raw request and can benefit from automatic refresh/retry logic and any other logic we'll introduce in the future. We can discuss potential gotchas regarding serverless vs non-serverless usage that Luke mentioned there as well. |
@pgayvallet This existing functionality allows authentication against 2 valid credentials and optional use the second set of credentials for custom work. Secondary authentication can be used such that the operator user’s credentials (e.g. Kibana user) is used to call the operator only REST APIs, but the normal user can be used to perform the transport action behind the REST API. So we can pass the operator only REST check, but swap out the user to do the actual work. |
Thanks for filing the issue and adding all the details @angorayc!
@angorayc covered it well in the previous comments, I just wanted to add that it's not really a new thing, since both Fleet and ML have already been leveraging secondary authentication for some time (I've learnt about it not so long ago though). And since we're going to have a third consumer that will rely on Happy to explain further if anything isn't clear, but essentially, we need a hybrid of |
So, I just checked with the ES team, and it appears that:
This second point makes is kinda awkward to expose a way to retrieve a full "secondary-auth-scoped" client that would send the header against all ES APIs, given we're not supposed to do so, which makes me wonder if that "third scoping method to client provider" is really the right approach. E.g. my fear is that it would be very easy to do things like: core.elasticsearch.asInternalUserWithSecondaryAuth(request).ping(); // ping doesn't support secondary auth Although I can't really think of any better quick wins enforcing better guard rails right now (as we really don't want to manually maintain an interface with the list of APIs that support secondary auth, right?), and in a way, that approach would probably still be better than having API consumers manually inject the headers as done (especially given direct access to authz headers is supposed to be something we've being trying to suppress since... well at least since I joined..) headers: { 'es-secondary-authorization': request.headers.authorization } |
But is it that bad? I mean, we already have a similar behavior for
Yeah, we definitely don't want to do that. |
For me, it's not really the same behavior. You can call any API with any user, and it may be rejected depending of the user's permissions First case is rejected because of authz, second case is rejected because of a bad usage of the API. it's not the same to me, is it? Now regarding
It would be fine. I just wanted to take a bit of time thinking about it, because changing the But I still don't see any better option (all "more DX friendly" alternative require to change the base |
I see where you're coming from, and, yes, the underlying reason for failure when either of these APIs is misused isn't the same. What I meant is that conceptually, the reason we have Ideally, for both
Sure, we're aligned here, and there certainly might be better options. It's just that I didn't manage to come up with anything more ergonomic, easily auditable, and still familiar to the existing consumers of |
@azasypkin I took a shot at trying to implement this, and I'm facing an issue regarding retrieving the right value to set to the I wanted to naively re-use the existing mechanism that retrieves the user's credential when creating the primary-scoped client: kibana/packages/core/elasticsearch/core-elasticsearch-client-server-internal/src/cluster_client.ts Lines 127 to 138 in 25b79a9
However I forgot that So my question is, from this Should I just naively assume there's only one entry in the record returned, and do something like |
I checked all our providers that create these However, if we want to make it less ugly, we can change our internal API: make Core expect just one header (or rather one header value, assuming it's always for the |
## Summary Fix #179458 Add a third method to `IScopedClusterClient`, `asSecondaryAuth` which allow performing requests on behalf of the kibana system users with the current user as secondary authentication (via the `es-secondary-authorization` header)
Describe the feature:
We need a way to access an ES API with
asInternalUser
and pass the current user's credentials at the same time viaes-secondary-authorization
.This could be a third “scoping” method to the Kibana Elasticsearch client, such as
asXXXSecondary
Our current workaround is: https://elastic.slack.com/archives/C06L0LC2LA0/p1711443697698389?thread_ts=1710963106.929479&cid=C06L0LC2LA0
Describe a specific use case for the feature:
In this case the API can remain internal but it still knows the current user's access right.
The text was updated successfully, but these errors were encountered: