elastic / kibana

Your window into the Elastic Stack
https://www.elastic.co/products/kibana
Other
19.69k stars 8.24k forks source link

[EEM] Allow REST call to enable EEM #197881

Open jasonrhodes opened 1 month ago

jasonrhodes commented 1 month ago

The current API for enabling EEM seems to be PUT /internal/entities/managed/enablement, and because it's marked as "internal" it means that it's not supposed to be accessed via external REST calls. For a demo we are doing with root-cause analysis, it would be very helpful to be able to do a PUT request to enable this as part of the environment setup, and I suspect this would be a common case for IAC contexts with customers.

Can we make that API endpoint public-facing for this use-case?

elasticmachine commented 1 month ago

Pinging @elastic/obs-entities (team:obs-entities)

miltonhultgren commented 1 month ago

Can we make that API endpoint public-facing for this use-case?

Maybe, but ideally we wouldn't need this endpoint at all. We currently need it due to the limiting security model we have, we would ideally see that be changed so that we can "enable" things like this by default.

But, if we imagine a world where we move a step away from materialized entities (by default) then we also will not need this kind of flow, so that may be the right route instead.

jasonrhodes commented 1 month ago

@miltonhultgren that all seems to make sense, but while the switch is needed it would be great if it was an API we can hit with code, vs requiring a UI click or a dev tools query run. Even using the header seems to have issues with API key auth, but I'm not sure if that's an internal API problem or something else. But because the API is internal, debugging it is a bit weirder.

klacabane commented 1 month ago

Made the enablement operations public in https://github.com/elastic/kibana/pull/198133 by changing the path from /internal/entities/.. to /api/entities/...

I don't think this has any implications since the product is tech preview and undocumented, but cc @roshan-elastic in case I'm missing something

miltonhultgren commented 1 month ago

I don't believe we should be so quick to make APIs public, specially for features that are in flux.

@jasonrhodes Can I ask two things:

  1. What is it that is calling this API in your demo? If this is an Elastic owned Terraform provider (for example) than I believe the general idea is that it's fine for them to use the internal headers (just like Beats or other tools do).
  2. What is the issue you're seeing when using the header in combination with an API key?

I would much rather we solve the API key + auth header problem instead of making this API public, both for the non-GA part but also because a public API is something we should approach with more care than simply flipping the access control, specially in light of our API guidelines and deprecation timelines.

roshan-elastic commented 1 month ago

I don't think this has any implications since the product is tech preview and undocumented, but cc @roshan-elastic in case I'm missing something

Hey @klacabane - thanks for reaching out.

From my point of view is that I don't mind things being possible to access as long as it's use at your own risk/undocumented (i.e. we don't have to support it) but I'm aware that there is probably more guidelines around this (as @miltonhultgren has mentioned).

This feels like a technical decision on how to meet Jason's ask but feel free bring me in if you need a PM angle to this.

jasonrhodes commented 4 weeks ago

Fair questions, @miltonhultgren, answers below.

  1. What is it that is calling this API in your demo? If this is an Elastic owned Terraform provider (for example) than I believe the general idea is that it's fine for them to use the internal headers (just like Beats or other tools do).

It's a demo setup script at the moment. Using internal headers is maybe okay, although which ones are required is a bit tricky to track down. There is also a kibana.yml flag you can set to get around this restriction, which has the effect of opening the cluster up and making ALL internal API endpoints "public".

  1. What is the issue you're seeing when using the header in combination with an API key?

I unfortunately don't have it saved, so I can't say for sure (I can re-run it later to try to get this info for you). It was an HTTP response error about access being denied, whereas the same key was being used successfully to create data views and alerting rules, and when changing to the user:pass auth, the same PUT request (with the special header) worked. With the API being /internal/ and requiring a special kibana.yml flag or header to get around that restriction, it makes it much more difficult to narrow down what the cause of a request error might be.


More generally, I would probably flip this question a bit to ask: what is the purpose of making an API like this internal? Seeing how easy it is to get around that restriction, it can't be used as a security consideration, so it seems to be mostly organizational at this point (with more potential security implications available in serverless, where it may not be as easy to get around). For an endpoint that, while it exists, would seem to ALWAYS need to be called by some external script, terraform, ansible provider, or other IAC tool, the idea of keeping it /internal/ seems counter-productive (from my perspective).

miltonhultgren commented 4 weeks ago

Is x-elastic-internal-origin not sufficient? We should lean on Core to document that for us, getting the right config should not be the blocker here, same for figuring out the bug behind combining that with an API key. I think we can agree that this is something we should resolve regardless of this specific API?

More generally, I would probably flip this question a bit to ask: what is the purpose of making an API like this internal? Seeing how easy it is to get around that restriction, it can't be used as a security consideration, so it seems to be mostly organizational at this point (with more potential security implications available in serverless, where it may not be as easy to get around). For an endpoint that, while it exists, would seem to ALWAYS need to be called by some external script, terraform, ansible provider, or other IAC tool, the idea of keeping it /internal/ seems counter-productive (from my perspective).

It's not a security concern for sure, I believe it's mainly two things:

  1. As I pointed out in my first comment, we really don't want to need this API, it's there because it has to be. It wasn't added to support onboarding automation via APIs.
  2. The whole system is still technical preview (and even that is barely), I don't really know what our approach is to "public API that is tech preview", hence our choice to leave all our APIs as internal for now since we don't want users outside of Kibana/Elastic to use them yet. Which is why I'm also not sure if we should casually make it public. I think we need to more carefully understand the deprecation path for a public API that might not reach GA.
jasonrhodes commented 1 week ago

Yeah, I don't think we (meaning Observability or Kibana in general) have a strong idea of what these API designations mean and are intended to do. I would think "tech preview" would govern whether something is going to be backward compatible, and internal/public would be more about security exposure (not sufficient for actual security but having API endpoints that are "less exposed"). But with the current situation of encouraging internal-marked APIs to designate that an API is not as stable as a public API, we need hack work arounds like "x-elastic-internal-origin" which then make these internal APIs somewhat public, as well.

For now, we can just use the UI for what we need here (dev tools or otherwise), and yes you're right that we should probably try to debug why the endpoint was failing with the API key. That said, having another layer of obfuscation around what might be going wrong when interacting with an API is, to me, not a great situation.