-
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
[Synthetics] Make core API key include read_ilm
privilege in Stateful only
#178897
[Synthetics] Make core API key include read_ilm
privilege in Stateful only
#178897
Conversation
🤖 GitHub commentsExpand to view the GitHub comments
Just comment with:
|
2e33341
to
0f78371
Compare
Pinging @elastic/obs-ux-infra_services-team (Team:obs-ux-infra_services) |
|
||
export const checkHasPrivileges = async ( | ||
server: SyntheticsServerSetup, | ||
apiKey: { id: string; apiKey: string } | ||
) => { | ||
const { isServerless } = server; | ||
const { indices: index, cluster } = getServiceApiKeyPrivileges(isServerless); | ||
return await server.coreStart.elasticsearch.client |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not related to your changes but this await
is not necessary neither the async
declaration. As the server.coreStart.elasticsearch.client
returns a promise the checkHasPrivileges client is the one that needs to await the response.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Totally agree, wish Kibana had a rule on unneeded async
/await
. I have this lint rule in the recorder and it makes the code a lot cleaner IMO.
I didn't notice it as I wasn't paying attention to the code around the bits I needed to modify.
I've also updated the function below this as it suffers from the same unneeded sugar.
635854b96805f29452cabc0a7dcb2a9a5194f6dc
}, | ||
], | ||
run_as: [], | ||
export const getServiceApiKeyPrivileges = (isServerless?: boolean) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reason why to accept undefined (isServerless?:
) here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -57,6 +57,7 @@ export interface SyntheticsServerSetup { | |||
uptimeEsClient: UptimeEsClient; | |||
basePath: IBasePath; | |||
isDev?: boolean; | |||
isServerless?: boolean; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also here why do we define it as possible undefined? I think this should be just true/false
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, this is fair. For flags like this that are based on config or some upstream dependency a lot of times I default to making them optional. But the code that sets this flag will always return a boolean, so it does make sense to make this field more opinionated. Just like the isDev
flag above this one could also be optional.
I've also changed the assertions on this flag from general truthy/falsey to explicit boolean assertion.
8ddc360658faa4ff161b2f24829df4797ec950c2
x-pack/plugins/observability_solution/synthetics/server/plugin.ts
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
a88b48e
to
a26c0d1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kibana security changes LGTM. Just one question on serverless integration test coverage. Also, I was unable to test manually due to lack of knowledge.
In the second step "As an admin, navigate to Synthetics and wait for the startup flow to display." I am not sure what this means. When I navigate to Synthetics I see this:
I tried creating an agent policy and location, but the API keys generated did not contain the synthetics writer section. How do I generate the synthetics API key?
@@ -74,7 +74,7 @@ export default function ({ getService }: FtrProviderContext) { | |||
], | |||
elasticsearch: { | |||
cluster: [privilege], | |||
indices: serviceApiKeyPrivileges.indices, | |||
indices: getServiceApiKeyPrivileges(false).indices, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we implement equivalent serverless api integration tests where we pass true?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I'm in the process of planning this with the Synthetics-on-Serverless team. I will likely do this in a separate PR that focuses just on implementing this. There will likely be other stuff that needs to change and it won't be a simple lift-and-shift. This will explode the delta for this change to many times its current size and require review burden from some additional folks who aren't on this PR already. Synthetics still isn't live in Prod, so nothing we do will impact existing early adopters, and we will likely include the API tests as acceptance criteria for switching on the plugin.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the second step "As an admin, navigate to Synthetics and wait for the startup flow to display." I am not sure what this means. When I navigate to Synthetics I see this:
Synthetics is designed to work with our managed SaaS testing locations by default. Locally, if you haven't run an instance of this service alongside your Kibana and configured them to talk to each other (requires Minikube and some extra setup), you'll be prompted to create your own "private" location, which involves enrolling an agent in Fleet and creating some config.
I tried creating an agent policy and location, but the API keys generated did not contain the synthetics writer section. How do I generate the synthetics API key?
To see this work locally end-to-end you'd need to also set up Fleet. The way we've done this in the past is via the elastic-package
's stack up
command. It's not super fun to get that working locally, however. The best way to test things end-to-end would be to deploy this PR to cloud QA. LMK if you'd like me to spin one up so you can see it working. This way you'd avoid having to set these things up manually on your local system.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do apologize, the testing steps require some knowledge of running Synthetics locally. I'll spin up a cloud instance of this patch so we can see it work in cloud.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, Justin! I don't think it's necessary to spin up a serverless instance - I trust the other reviewers have given this a thorough testing, I just wanted to understand why I wasn't seeing what I thought I should - I don't have any experience with synthetics. This makes sense to me now. I appreciate the time you took to explain.
And thank you for the follow up re:tests. Is there an open issue for this work already?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not yet, I will make the ticket before I merge this though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Issue is linked. I will probably merge later today, or tomorrow morning.
/oblt-deploy |
a26c0d1
to
49f356e
Compare
@jennypavlova @cauemarcondes could you please give another review, after speaking to the Kibana team this is the way they recommend handling Elasticsearch capability-related considerations when determining if we need to adjust for Serverless or not. |
server: SyntheticsServerSetup, | ||
apiKey: { id: string; apiKey: string } | ||
) => { | ||
return await server.coreStart.elasticsearch.client | ||
const { indices: index, cluster } = getServiceApiKeyPrivileges( | ||
server.coreStart.elasticsearch.getCapabilities().serverless |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@justinkambic could we keep exposing the isServerless
in the SyntheticsServerSetup
definition? this is a long chain of functions to remember to check if it serverless or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cauemarcondes the Kibana team stressed that Kibana's buildFlavor
and es capabilities
(which is basically Elasticsearch's build flavor) should be treated as two separate things. It's a bit pedantic but the two aren't synonymous and there's no way to know if there will be important differences in the future.
I agree that this implementation isn't great because of the lengthy call chain, and it's not DRY, so we should improve it as you suggest. I can add an isEsServerless
flag to the plugin class and reference it in the server object that gets injected in place of this. 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
… flavor when determining how to interact with ES.
b2d9433
to
30ddac0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
💚 Build Succeeded
Metrics [docs]
History
To update your PR or re-run it, just comment with: |
Summary
Resolves https://github.com/elastic/synthetics-dev/issues/332.
ILM is not a concept in Serverless. As such, when the Synthetics plugin requests the
read_ilm
permission for its core API key during bootstrapping, it's asking for a priv that will eventually not exist on Serverless, and ES will give an explicit deny for the request, which will probably cause Synthetics to crash and not be functional.The fix is to detect the build type at startup time and enable the server plugin to determine whether it needs to include this privilege or not, based on whether Kibana is running in stateful or serverless mode.
Testing
You can easily test this in both modes. The steps are the same.
NOTE: when testing serverless, if you include the flag
-E xpack.security.authz.has_privileges.strict_request_validation.enabled=true
this will simulate the manner in which Elasticsearch will explicit deny the API creation request when this is enabled in the MKI environment, and thus you should include it in your testing.read_ilm
included under thesynthetics_writer
object, shown below. For serverless, you should not see this priv in the list.Stateful API key perms
Serverless API key perms