-
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
SavedObjects should support importing/exporting even if they're hidden from the API #82027
Comments
Pinging @elastic/kibana-platform (Team:Platform) |
Regarding tags: the Your suggestion would work, as long as This proposition would still mean that all @kobelb maybe you have a better vision that us on that? |
I think it's an interesting suggestion. From the authorization perspective, I think we could make it work as we have a "Saved Object Management" feature which conceptually allows the user to import/export anything that we consider to be a saved-object. So even if we end up skipping the authorization implemented in the custom clients, we could still ensure that the end-user is authorized for the import/export operation itself. As far as I'm aware, it'd take additional effort to do authorization on import/export, as this relies on the authorization implemented within However, this alone wouldn't fix situations like Alerting, as they need to create tasks with task-manager and create API keys on import.
I wouldn't say that I have a "better" anything than you all, but like always, I have an opinion I'm willing to share 😄 At the moment, |
atm users can directly call the endpoints for import or export without using the UI. This authorization 'issue' is already present. I thought we were fine by assuming that read permission to a SO type grants export permission, and that write permission to the type grants import permission?
We got two export needs for tags (sorry, should probably have started with that):
This would be addressed by the proposition
For that case, as we are exporting from the wrong side of the relation, I was planning to manually find all objects referencing the tags, and perform an export 'by objects', using kibana/src/core/server/saved_objects/export/get_sorted_objects_for_export.ts Lines 144 to 149 in d4b2a51
This would be working - for now - as directly using |
I agree with your description of the current behavior, and I agree that it's fine to keep it this way. I was attempting to propose that we change it so that you could only use import/export if you have the saved-object management feature. The import/export authorization would still be performed, but the custom authorization in the custom clients would just be skipped. As far as I'm aware, the custom authorization in the custom clients is being implemented so that end-users can have access to a subset of saved-object types. For example, Alerting wanted to have a singular
Why don't we want tags to be listed in the SO management section? It seems like this would allow us to easily export all tags and their related saved-objects using the existing UI and logic. In my opinion, ideally all Kibana saved-objects would be exportable/importable in saved-object management, as this allows users a single place to export all of their saved-objects. Not being able to export a tag, unless it happens to be related to another saved-object that you're exporting, seems like a weird user experience. |
So add an api-level check on the endpoints and then use the internal client to perform the operation?
So, technically first: No it doesn't. The relation between a SO and a tag is in the 'wrong' direction for that to work (it's SO->TAG, not TAG->SO). Exporting a tag from the SO management section actually just literally do that, it exports the tag object, alone. This is why we will be adding an 'export tag and relative objects' action from the tag management section, as we need a 'reverse relation' logic when generating the list of objects to export (find all objects assigned to the tags, then use the same references gathering logic we already do, but from these objects instead of the tags). Now, functionally: Product want |
That's what I was initially thinking, yeah.
You're right. When you chose to "include related objects" during export, it's only including the "children" not the "parents".
If we go with this approach, it will be in contrast to how index-patterns are currently handled. Index-patterns have their own management section but also show up on the saved-object management screen. It will also potentially create a two-step process for end-users who wish to "export all of their Kibana data", because now we'll have to direct them to export all saved-objects, and if they happen to have any tags that aren't currently being referenced we'll have to instruct them to then export all of their tags. |
I feel like there are opposing ideals of what Saved Object Management should be and perhaps this stems from us not having a clear vision for this feature. On the one hand we want to allow users to export all their Kibana data, and essentially we're opening up the internals of our "database" to users showing them everything that's stored there so they can make a backup. On the other hand tags and spaces are modelled as magical "system" data, but that also needs to be exported somehow to be able to fully restore your data. I wonder if some of this conflict comes from the "management" of Saved Objects. Maybe this UI should only have "create a backup" or "restore a backup". If they want to do "management" activities like selectively export a dashboard or sharing it to a different space, this should be done from the UI of that entity. So if I want to share a case or export a case I go to cases management and select the case. Anything short of a full backup happens inside the plugin. This means that cases can include all the entities, value objects, relationships (parent or child) etc when exporting. A slightly different alternative would be to keep Saved Object Management but then we don't list all the saved objects in the system. Instead we ask all plugins "what entities do you have that a user can backup?". Cases will say, here's all the cases (and will already embed any comments etc inside). When a user imports the objects we pass these to the plugin again and say "a user wants to restore these alerts objects". This way we separate our database (the actual saved objects) from the domains that are built on top of them. It's probably still a good idea to embed value objects inside an entity, but it's not so critical how the data is modeled, it becomes an implementation detail of the plugin that users don't need to understand. |
Valid point. This is a product decision, though. Adding @alexfrancoeur @ryankeairns in the loop FYI, but we may want to create a new issue for this specific subject, as the current one is more around the technical and architectural design of the export/import process.
Can't agree more on that
I'm not oppose to the idea, however
Which is why I think your second proposal is probably more doable or 'realistic'
I think this always has been the vision. This is what the
First obvious problem I see with a basic implementation of what to describe would be the SOM pagination / filtering / searching. As objects would now be retrieved from multiple sources, it will be a nightmare to address: all these 'objects providers' would need to support pagination, filtering and so on... However, I agree, and the current discussion confirms it, that we need some way to let type owners have their word regarding the export and import processes. Ideally, We would still be able to retrieve the list of objects listed in SOM ourselves (and ideally++ in a single ES query against the SO index), but we would expose additional APIs to let plugins alter this list of object before the export. It could be to add dependencies that are not listed as references, redact some fields, generate a 'super' object that would be an aggregation of other (thinking cases + comments here)or any kind of processing. The same would apply for import. SOM would still be the single entry point to import a 'dump'/'backup' or whatever, but we would be calling the type owners for each object to preprocess the objects before reinjecting them into ES. this preprocess would include data processing, creating (and adding to the import 'on the fly') objects that where aggregated during the export, and so on. (of course, I have no idea how these changes would work with import conflicts) |
++
What prevents plugins from modeling SO from the very beginning in such a way? Lack of recommendations on the best practices?
What about complex export cases when async actions required? Like |
That is probably the conversation in progress here: #72028, but in short: The fact that the SO http API are currently 'the way to go' for SO interactions, and the fact that these APIs are manipulating raw SOs probably is the main cause of our current situation.
It probably depends (tm) on the kind of async actions we're talking about. Decrypting SO attributes per instance, could be async (like if the hook needs to access the FS, or any other node-base reasons to have a async method). In that case, SO import/export should probably support async 'hooks'. For more complex actions (I'm mostly thinking about actions that require user input), redirecting to the type 'owner plugin' to fix in context could be an option. My main question in that case is how do you manage, from SO management, the workflow to handle multiple 'failures' requiring different user actions? Say, you import alerts, dashboards, cases, and they all require some user interactions to fix the import on each individual types. The workflow to allow the user to be directed, in a 'seamless' workflow, on each app to fix in context seems very complex, and maybe more work that allowing some kind of 'UI hooks' for type owners to plugin into the import process? As a side note, I feel that this discussion may be diverging. From my understanding, the prime goal of the issue was to answer the base need of exporting hidden SO types, not to try to fix all the other problems required for #82020 regarding SO exports. Else we risk some overlaps with other issues such as #82064 or #72028. OTOH all these issues are tightly coupled, and we might want to use a single one for all the part of the 'meta' discussion, I'm not sure. |
Today, a few of us had a synchronous conversation regarding some of the great questions that were raised in this issue. I've attempted to summarize what we've come to an agreement on and the topics which are still debated. For those of you who were there, please keep me honest; and for others who were unable to attend, please feel free to voice your objections to any conclusions that were reached in your absence:
|
I think this issue made us think through a lot of related issues; however, I think we should constrain it to the original purpose that @rudolf stated:
When the developer registers a saved-object that is
I created #84976 as a proof-of-concept doing so for Alerting; however, there are additional changes that are required for Alerting to be able to do so. The part that I feel the most uneasy about is the changes to the privileges model. With these changes, when a user is granted access to the saved-object management feature, they're authorized to perform all CRUD operations on importable/exportable saved-objects even if they're hidden. However, they can't do so using any of the APIs besides the above because of the implementation of hidden types. @legrego, I'm interested to hear your thoughts on this. |
The authorization changes to the SOM feature that you made here feel ok to me. In fact it's probably more correct than what we previously had, since the intent of those privileges was to facilitate import and export operations. We've already accepted that SOM is an administrative feature, so allowing them to do administrative actions that aren't otherwise possible seems reasonable to me. One caveat just came to mind if we were to allow this: For Alerting specifically, this will cause inconsistent audit records: the import/export operations will be audited as generic saved object CRUD events (as if they were a "regular" saved object). When interacting with Alerts through their dedicated APIs, we generate more specific audit events. This will be even more pronounced in 7.11 with #84113. I don't think this will cause any gaps in audit coverage, but someone searching for the alerting specific audit events could very well miss these since they'll be recorded slightly differently. |
I read |
I wonder if we can take advantage of the |
Yeah that sounds like it'd work! I wasn't aware those were in scope for this discussion, based on the earlier comment of constraining this to the original purpose of the issue. |
@legrego should the |
Will the current issue expose this support for alerts or actions, or will we complete this initial work without turning it on for those types? I don't mind splitting up the work into different PRs, but I would like to have |
From a quick look, kibana/x-pack/plugins/alerts/server/saved_objects/index.ts Lines 39 to 45 in e45b76c
kibana/x-pack/plugins/actions/server/saved_objects/index.ts Lines 20 to 26 in 4f6df62
|
In addition to the API/Export behaviour, hidden saved object types are also hidden from the saved object clients. In order to access a hidden type (and still scope the security to the incoming request) a plugin would have to construct a new scoped saved objects client. This means they can't use the existing scoped client exposed through the request handler context, it will also affect the ergonomics of export hooks #84980 (comment) So I wonder if we shouldn't change the behaviour of |
To clarify: are you proposing that plugins will automatically get access to their own What I'm not keen on is for all plugins to automatically get access to all |
From my understanding, what @rudolf is proposing is that all hidden types will be accessible from any server-side SO client.
@rudolf I'm not sure to see the exact need here. the Imho all we (eventually) need would be a new As a sidenote, I'm currently in the process of refactoring the export/import code (#86264) to have it accessible via the SO service/context instead of static imports, which will also help for all future improvements of these features |
I like this approach. When a saved-object type is hidden, we want to require that all access to these saved-objects goes through the custom client. If we automatically made these hidden types accessible to the entire plugin, this weakens that protection. |
I guess I was questioning the usefulness of hiding hidden types from the client since this doesn't provide any real security. But I agree that hiding it from the client can help prevent security bugs where a developer thinks they're working with a non-hidden saved object.
I'm +1 on this solution. |
Some saved object types would like to prevent users interacting with them through the auto-generated saved objects API but still allow users to import and export these objects for backup purposes.
Examples:
We could start by still allowing exports for objects with
hidden: true
andmanagement.importableAndExportable: true
. However cases and alerts implement their own security in their API layer and we should not just allow any user to export any of these objects.The text was updated successfully, but these errors were encountered: