-
Notifications
You must be signed in to change notification settings - Fork 8.1k
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
[Actions][Cases] Case Connector RBAC Discussion #94498
Comments
Pinging @elastic/kibana-alerting-services (Team:Alerting Services) |
Pinging @elastic/security-threat-hunting (Team:Threat Hunting) |
@jonathan-buttner thanks! We will review 🙏 cc @kobelb |
I did a first pass read, which is in line with what I was thinking for the RBAC expectations. This will be useful input for #70303. Do we have an idea when you want the case connector to ship? With RAC, I'm guessing this is delayed? |
Thanks for taking a look Mike! @XavierM can you chime in on the roadmap? I think we were hoping to complete the connector and RAC stuff in the same release |
We have a meeting tomorrow with our PO about case connector in 7.13.0 for security solutions and we will be able to talk about it with them. However, I do think that we will need case connector sometimes for 7.last because Case without alert(s) won't be really useful. @mikecote Which version of 7.x will be realistic for you to have this feature? And we might be able to give a hand in 7.14.0 |
Let me know how the meeting goes tomorrow. If you can confirm this is critical for 7.x, I'll discuss with the @elastic/kibana-alerting-services team about researching this. Then, come up with a proposal and a list of questions that we'll need to answer before moving on to the implementation stage. Let's make sure the automatic case creation is a priority first (on top of the manual "create a case" button). From a high level, this seems like a medium to large size effort and we've been tracking it with #70303. |
Thanks for the summary @jonathan-buttner I gave it a first pass and nothing jumped out at me, so without going into the details of it, this sounds well aligned with what we discussed. There is one thing that does warrant some research - we currently treat It might mean we need to separate the We recognised this complicated need a while back as part of #69442, but haven't had a concrete need to prioritise that work until now. * For the record, the same happens if a user adds an ES Index connector and points it at an index they don't have write privileges for |
Pinging @elastic/security-threat-hunting-cases (Team:Threat Hunting:Cases) |
Will be handled by #160367 |
This issue is to follow up on a discussion the Cases team had with Mike and Gidi about the case connector RBAC implementation. I'll try to give a high level overview of how we expect the Case RBAC solution to work and how it will interact with the case connector.
Background
Attaching alerts to a case using the case connector
To attach an alert to a case, a user can leverage the case connector
.case
and provide a case ID to the connector's_execute
API. To create a case connector the following would be provided in a post request:To add an alert to a case the following call can be made:
The case connector's execute function handles adding the provided alert information within the
comment
field to the specifiedcaseId
.Case RBAC
Case Class
To represent multiple types of cases within a single saved object type, we leverage a field called
owner
within the saved object to indicate the type of case. If a case is created in the Observability plugin we will set theowner
field toobservability
. If a case is created in the Security Solution plugin we will set theowner
field tosecuritySolution
. This field will be passed as a parameter to the API that handles creating a case.When a plugin registers a feature, it can specify which owners of cases a user could be given access to when granted that specific feature privilege. For now we can assume that a single feature will only register a single owner of cases. For example, in the observability plugin, a new feature privilege will be created called
Cases
which when granted will give a user access to theobservability
owner of cases. This will be very similar within the Security Solution plugin. When a user is granted access to theSecurity
feature within the Security Solution plugin they will be granted access to thesecuritySolution
owner of cases.A single user can be given access to multiple features and therefore could have access to multiple owners of cases.
Creating a Case
When a case is created, the
owner
field must be specified as part of the request. The cases RBAC implementation will use theowner
to build a URI likecases:1.0.0:securitySolution/create
. This URI will be provided to the security plugin to determine if the user making the request has the correct permissions to create asecuritySolution
owner of cases. If the user has only been granted access to theobservability
owner of cases then authorization will fail.Finding a Case
When a request is made to retrieve a list of cases, a query parameter indicating the
owner
of cases will be provided. The cases RBAC implementation will use theowner
to build a URI likecases:1.0.0:observability/find
. This URI will be provided to the security plugin to determine if the user making the request has the necessary permissions to view anobservability
owner of cases. If the user is authorized to view the specified owner of cases, a KQL filter will be constructed and passed to the saved object client to only retrieve cases of the specified owner. In the future it could be possible for multiple owners to be provided in the find's query parameters if we provide a view for multiple owners of cases at one time. For now we can assume that only a single string will be provided.Authorization within the Case Connector Execute Method
When the case connector's
execute
method is called, the RBAC implementation will retrieve the case'sowner
using the providedcaseId
. It will then build the URI using thatowner
and provide it to the security plugin to determine if the user making the request has the correct permissions to perform thesubAction
specified. To do this, some request or callback mechanism must be provided to theexecute
method.Global Case Connector
The case connector is a little different from other supported connectors in that there should only be a single case connector per space within Kibana. The case connector does not have any configured fields and all the parameters are passed when the
_execute
API is called. Ideally, the case connector should probably be created on boot up of kibana.Case Connector Scenarios
This section will go through some scenarios and explain what the ideal behavior should be.
No Case Permissions
Permissions
If a user without permissions to view any owner of cases attempts to create a case connector, the actions plugins should return an error. As I mentioned before, the case connector should really be created by the system on boot up anyway. If a user without permissions to view any owner of cases attempts to call the
_execute
API, the actions plugin should return an error. I don't think this functionality is necessary to provide a fully secure system but it would provide a better user experience. As mentioned above theexecute
method could handle authorizing if the user has the correct permissions. Unfortunately we wouldn't be able to provide any information to the UI since the case connector action would happen outside of the alerting UI flow.Observability Case Class Permissions
Permissions
Available Cases
Originating Plugin: Observability
A user with the above permissions should be able to either create a new case with
owner: observability
or retrieveObservabilityCase1
. Either can be used as thecaseId
to add alerts with the_execute
API.Security Solution Case Class Permissions
Permissions
Available Cases
Originating Plugin: Security Solution
This scenario is essentially the same as the observability one above, except that the user should only be able to select/create an
owner: securitySolution
case.Unprivileged User Update
User: PrivilegedObsUser
Permissions
User: UnprivilegedObsUser
Permissions
Let's say user
PrivilegedObsUser
creates an alert and chooses case as the connector. If the unprivileged userUnprivilegedObsUser
attempts to update the alert, ideally the update should return an error. This is because the API key will be updated to the unprivileged user which will cause a failure when the alert fires and the cases RBAC implementation checks the user making the original request to add an alert to a case.To enforce this we'd probably need the alert's
update
method to make a call through the specified connector to determine if the user doing the update is authorized to use the connector (from the connector's point of view). Theupdate
method would need to provide thecaseId
and the user making the update request. It could then retrieve theowner
of the case and determine if the user making the update request has access to that owner of cases (in this case it wouldn't).If we don't enforce it in the
update
method the case RBAC implementation will throw a forbidden when theexecute
method is called. The system will still be secured but the user experience isn't ideal since we'd just log the error but nothing would be displayed in the UI.Another option would be to retain two separate users, one for executing the action's connector and another for the alerting framework.
Almost Privileged User Update
User: PrivilegedObsUser
Permissions
User: PrivilegedSecUser
Permissions
Let's say user
PrivilegedObsUser
creates an alert and chooses case as the connector. If the unprivileged userPrivilegedSecUser
attempts to update the alert, ideally the update should return an error like the scenario above. Again we could accomplish this using the call-into-configured-connector approach to determine if the user doing the update is privileged enough according to the connector.Mismatched Create
Permissions
Originating Plugin: Observability
The user with the above permissions can create an alert, but it'd probably be ideal if we hid the case connector as an option in the UI. This would be ideal because the user does not have the necessary permissions in the originating plugin of the alert. To successfully attach the generated alerts to the
observability
owner of cases, the user needs the Cases privilege within the Observability feature. If the user were doing this all through the API then the case RBAC implementation would have to catch it. To implement this functionality in the UI we'd need some mechanism to call into the configured connector like in the previous scenarios to determine if the user making the request has the appropriate privileges within a particular view (in this scenario the observability view).Creating an Alert through the Management Page
If a user creates an alert through the alerts management page and has the necessary privileges to use the case connector, the
owner
should bealerting
.Conclusion
Given that a user that lacks the cases privileges for an owner of cases can arbitrarily make a request to the case connector's
_execute
API with acaseId
, theexecute
implementation must be able to authorize the request. I might be missing something but I think given the current API implementation for connectors, it needs to be up to the connector to handle the authorization instead of pushing that logic up into the action framework.The security plugin's API contract requires a
KibanaRequest
object to authorize the user:https://github.com/elastic/kibana/blob/master/x-pack/plugins/security/server/authorization/check_privileges_dynamically.ts#L17-L19
In addition to this, connectors that leverage hidden saved objects need a way to construct a saved object client with access to specific hidden types. This could be accomplished using the raw context or maybe a callback method within the framework to retrieve a saved objects client given an array of strings representing the needed hidden types.
The text was updated successfully, but these errors were encountered: