-
Notifications
You must be signed in to change notification settings - Fork 8.2k
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
[Cloud Security] CSP Integrations PLI auth block #182110
Closed
Closed
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
… in forms and to have the upsellingcomponent hook shared in our plugin
/ci |
💔 Build FailedFailed CI StepsHistoryTo update your PR or re-run it, just comment with: |
I'm closing this in favor of a preferred method which can be seen here: |
3 tasks
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Resolves #179412
Video showing that the PLI auth block is only showing when missing the correct PLI, and that it does not effect other integrations
Screen.Recording.2024-05-27.at.19.00.03.mov
Problem
During development, we encountered a challenge with retrieving
upsellingServices
in our integration forms. This issue was caused by the inability to declaresecuritySolution
as a dependency due to cyclic dependencies. Additionally, wrapping our forms in the security solution context was not feasible since they are registered immediately on plugin startup without being wrapped by our context wrappers.Solution
There were a few optional solutions, but each had its ups and downs. I've settled on the following solution:
Registering upselling component
kibana/x-pack/plugins/security_solution_serverless/public/upselling/register_upsellings.tsx
Lines 164 to 168 in 2da2e32
In
security_solution_serverless
plugin, we register our upselling component according to this guide. The registration includes the component itself, a registration id, and the required PLI.Declaring
securitySolution
as a runtime dependencykibana/x-pack/plugins/cloud_security_posture/kibana.jsonc
Line 27 in 2da2e32
In
cloud_security_posture
plugin we declaresecuritySolution
as a run time dependency, this allows us to usecore.plugins.onStart('securitySolution')
, which is an async method to fetch a plugin contract. Please refer to the PluginsServiceStart interface for more information.Note that I was not able to use this hook from our
useKibana
services even though it does returnplugins.onStart
. I suspect this is also caused due to missing context at the point of registering the integration form, since I was able to use the hook fromuseKibana
on other pages which are rendered inside our context wrappers.Passing
securitySolution
contract into our integration formkibana/x-pack/plugins/cloud_security_posture/public/plugin.tsx
Lines 58 to 65 in 2da2e32
We pass the method into our integration form and call for the registered security solution runtime dependency.
The expected response is the security solution contract, part of this contract is the upselling services which includes a map for registered components (referred to as
sections
by this service).We can get our component from the sections map manually. This component will only return in case the current PLI is lower than the required PLI we registered the component into.
Adding PLI auth block state in
fleet
kibana/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx
Lines 452 to 461 in 2da2e32
In
fleet
, I've added a new state dedicated to rendering the form wrapper without the actual form or bottom bar, which included interaction buttons, but only the component which will be set into the state. That is to to comply with our design and product demands. I named the state aspliAuthBlockComponent
but it can be any component. for the Fleet reviewer, let me know thats ok or would you prefer a more generic naming convention. The set state method is being passed into thereplaceDefineStepView
component, which we use in order to render our custom forms.Handling the PLI block state
kibana/x-pack/plugins/cloud_security_posture/public/components/fleet_extensions/policy_template_form.tsx
Lines 551 to 563 in 2da2e32
Back in
cloud_seucity_posture
integration form, in case we receive our registered component from the upselling service, the set state method will be called, setting our PLI block component and preventing the user from interacting with the page without upgrading its project. Since the execution of this set state method is being controlled by the individual component it was passed into the fleet page itself is oblivious. It is the responsibility of the executioner to make sure this state is only being passed a component, based on the matching PLI needs, and only on serverless environment.Downsides
security_solution
infra since we are technically a part of it. but because of early decisions, we are rendered on a different scope and their internal infra is unavailable to us unless we expose it by manually inserting it into our security solution context wrapper, which as mentioned, does not wrap the registered forms.Alternative Solutions
Using Fleet's UI Extension infrastructure
Initially, we explored leveraging Fleet's existing infrastructure to register a new view for
pli-auth-block
, allowing all packages to utilize this view to render their PLI blocks. The concept was to register the upselling component as usual and then register it into the UI Extension service, which wraps Fleet. Since Fleet's UI is affected, it seemed like a logical approach. This would mean we don't have to add any new dependencies, and not copy any code into our plugin. all logic would be controlled from Security Solution Serverless upselling and Fleet's UI Extension.However, this direction presented a few challenges. Firstly, it introduced code complexity with double registrations of lazy components. Secondly, it was difficult to reliably detect whether the upselling component returned as a component or not. Since the return value of the registered view was consistently a lazy component (even if it would eventually result to
null
), making conditional rendering unreliable.Additionally, This approach centralized the rendering decision in a higher hierarchy. Meaning other integrations were exposed to being blocked by PLI requirements of unrelated integrations if a mistake occurred for one integration.
While leveraging Fleet's UI Extension infrastructure initially seemed promising, we found that its complexity and potential impact on other integrations' PLI handling outweighed its benefits.
Copy pasting upselling service into Cloud Security Posture plugin
Copying the upselling service code into the Cloud Security Posture plugin would spare us from having to work around cyclic dependencies with async calls for the plugin's contract on run time. However, it introduced maintenance overhead due to managing a large portion of copied code, which could cause divergence from updates made to the original upselling service and potential bloated and redundant code.
Exposing upselling service to a different plugin in order to import it without cyclic dependencies
The idea was to import the upselling service from security solution to another plugin, exposing it from that shared plugin, and importing the service to our cloud security solution plugin, without having cyclic dependencies.
This option was not actually tested, I fear it might be unconventional and could lead to confusion or unexpected behavior. I also have some concerns with the added complexity in managing dependencies between plugins. As well as feasibility concerns due to limitations in plugin architecture: we export the plugin's API from its
index.ts
file, but have access to imported plugins APIs from thesetup
andstart
functions in theplugin.ts
file.