-
Notifications
You must be signed in to change notification settings - Fork 894
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
[Doc] Add workspace access control design proposal #4633
base: main
Are you sure you want to change the base?
[Doc] Add workspace access control design proposal #4633
Conversation
Signed-off-by: Yan Zeng <[email protected]>
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 for writing this up. I might have some misunderstandings about the system evolved, could you add some more flow diagrams / sequence diagrams to clarify how parts of this system interact?
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 for making this a pull request, much easier to put inline feedback on the design and for follow up.
|
||
## Design | ||
|
||
### Personas |
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.
These personas are defined by their level of access to the system, not by their goals. I'd recommend abstracting what/how of permissions in favor of what the personas are trying to accomplish within a workspace.
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've pondered my feedback and here's why focusing on user goals matters. If we rely heavily on pre-existing permission structures, our solution's scope might be unintentionally limited.
Starting from scratch for workspaces lets us independently define requirements, leading to a flexible and efficient system tailored to users' needs. We should strive to understand user needs and goals, and not be overly bound by existing permission systems.
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'm not sure if I fully get what you recommended, I'll try to reply based on my understanding.
If we rely heavily on pre-existing permission structures, our solution's scope might be unintentionally limited.
If the pre-existing permission structures
you're referring is the personas defined here, I think our implementation won't rely on that.
For a workspace, we abstracted 4 types of permission:
write
, user can write(include delete) to the workspace object as well as the ACL defined on the the objectread
, user can read the workspace objectlibrary_write
, user can create/update objects, such as dashboards, visualizations associated with the workspacelibrary_write
, can can read objects, such as dashboards, visualizations associated with the workspace
A workspace admin is write
+ library_write
A workspace operator is read
+ library_write
A workspace viewer is read
+ library_read
Does this address your concern?
|
||
Please note that, the workspace admin, operator and viewer persona are specific to the workspace. e.g. one workspace operator in one workspace can be an admin in another workspace. | ||
|
||
super-admin is a stack level role, it can be configured in the `opensearch_dashboards.yml` config file. |
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.
Down a couple of paragraphs you mention not using RBAC, maybe this belongs elsewhere or incorporated in another way?
Who a super-admin is seems like something that shouldn't be statically defined as such I don't think a config file that requires a restart of the service to pick up is a good place to manage this informatino. Maybe breakout another doc/section for how to address items like 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.
This part needs to update because super-admin can not only be configured statically in opensearch_dashboards.yml
, but also can be configured via dynamic application configuration: #5855
### Discretionary Access Control for Data Access Control | ||
|
||
In order to support allowing a resource owner to manage the access to the resource feature, we can employ discretionary access control model. The idea is that, for each OpenSearch Dashboards saved object, we can attach an ACL (access control list) to it to save the principals and permission to operate that saved object. When a user is attempting to perform any operation on that saved object, we will first of all evaluate the ACL and then allow or deny the operation accordingly. | ||
|
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.
Add a diagram to help illustrate the relationship, here is a diagram along with the code to add it inline. BTW If I got this relationship wrong please update :D
BTW I asked ChatGPT to generate an outline for this diagram if you want to streamline their creation
graph LR
subgraph Dashboard
DashboardObject["Dashboard Object"]
end
subgraph ACL1
ACL11["Access Control List Entry"]
ACL12["Access Control List Entry"]
end
subgraph ACL2
ACL21["Access Control List Entry"]
end
DashboardObject --> |Associated with| ACL1
DashboardObject --> |Associated with| ACL2
style DashboardObject fill:#FFE4B5,stroke:#333,stroke-width:2px
style ACL1 fill:#ADD8E6,stroke:#333,stroke-width:2px
style ACL2 fill:#ADD8E6,stroke:#333,stroke-width:2px
```mermaid | |
graph LR | |
subgraph Dashboard | |
DashboardObject["Dashboard Object"] | |
end | |
subgraph ACL1 | |
ACL11["Access Control List Entry"] | |
ACL12["Access Control List Entry"] | |
end | |
subgraph ACL2 | |
ACL21["Access Control List Entry"] | |
end | |
DashboardObject --> |Associated with| ACL1 | |
DashboardObject --> |Associated with| ACL2 | |
style DashboardObject fill:#FFE4B5,stroke:#333,stroke-width:2px | |
style ACL1 fill:#ADD8E6,stroke:#333,stroke-width:2px | |
style ACL2 fill:#ADD8E6,stroke:#333,stroke-width:2px |
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.
+1, but perhaps an even higher level one that has both workspaces and objects and how the overlapping permissions work
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.
one that has both workspaces and objects and how the overlapping permissions work
@davidlago The current implementation is it should either pass the permission check of workspace or the object's ACL validation
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.
@peternied We store the ACL data as part of the object(as a property), not with a separate object.
|
||
In order to support allowing a resource owner to manage the access to the resource feature, we can employ discretionary access control model. The idea is that, for each OpenSearch Dashboards saved object, we can attach an ACL (access control list) to it to save the principals and permission to operate that saved object. When a user is attempting to perform any operation on that saved object, we will first of all evaluate the ACL and then allow or deny the operation accordingly. | ||
|
||
#### Why not using role based access control model |
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 don't think 'roles' are a fundamental problem, I think the problem is calculating what permissions a user has, with the current system there are no APIs do to this making the only avenue to attempt to perform an action and check for 403 (bad user experience).
Might want to leave the door open in the design to allow permissions to be source from other logical groups such as roles that might be useful in the future for larger numbers of workspace users.
IMO I think this problem is mitigated if you could see a projection of an individual's users permissions, e.g. potential way to see permissions where you can get a full list, and that list has references to the source of the permission:
GET /user/{USER_ID}/_permissions
{
"user": "{USER_ID}",
"permissions": [
{
"name": "WORKSPACE.VIEW",
"scope": "*",
"from": {
"source": "role",
"roleName": "AllUsers",
"ref": "/roles/AllUsers"
}
},
{
"name": "WORKSPACE.EDIT",
"scope": "index",
"from": {
"source": "user",
"ref": "/user/{USER_ID}"
}
}
]
}
|
||
### Workspace and Saved Objects | ||
|
||
Workspace is a newly introduced type of OpenSearch Dashboards data, it is a container which organize the functions and saved objects, so the saved object in a workspace inherit the permissions settings from the workspace. One saved object can potentially in multiple workspaces, thus it inherits the permission settings from all the workspaces it is assigned to. |
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.
When you say inside, that seems more like a logical reference to 'associated with'. I'm concerned about inheritance when there could be multiple workspace with conflicting rules. As there are difference kinds of access read vs readwrite, if so this could make associating a saved object with multiple works spaces cause trouble - which permission do you get the lowest vs highest?
This inheritance creates side effects where modifying a workspace permission can change the permissions on objects inside other workspaces
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.
This phrase is missing a key verb:
One saved object can potentially in multiple workspaces
can be in? can be referenced in?
I echo @peternied's sentiments about the undesired side effects. Will saved objects be addressable outside of a workspace, or will they always be nested inside of a workspace? i.e. if object1
is associated with workspace1
and workspace2
, can I link to object1
directly, or do I need to qualify with workspace1/object1
? If so, could we skip the "it inherits all permissions across workspaces" so that it only gets those in the context it is being referenced?
{ | ||
"permissions": { | ||
"management": [ | ||
"group/finance_manager" |
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.
Is there a system that will translate this into a principal/set of principals? Or is this assumed to be a principal part of the AuthN 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.
As state at the beginning:
We can assume the users are authenticated and user profile (user name and group info) has been injected into each request
It expects AuthN system to inject these information
* a user can create saved object in a workspace if they have library_write permission of the workspace | ||
|
||
|
||
#### ACL |
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.
While named differently, these ACLs look like roles, how are they different?
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.
As both of them are mechanisms used in access control systems, they do share similarities, but they operate at different level.
ACLs focus on defining permissions at the object level for individual resources, roles abstract away permissions into named collections that can be assigned to users or groups based on their roles.
Does this answer your question?
ACLs can be considered as sub-resource or attributes of a OpenSearch Dashboards data record, so users who have the write permission to the data record can modify the ACL. | ||
|
||
**Orphan objects** | ||
This means a user can remove themselves from the ACL of a saved object. Once a user self-remove from a saved object’s ACL, other user having write permission can add the user back if needed. We can add additional checks to make sure any saved object will at least have some identities in the ACL to avoid orphan objects. However, in the case that the only owner of the object get removed from the user directory, which caused the objects becoming orphan, we will need super-admin to get involved to deal with the orphan data records. |
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.
Requiring the intervention of a super-admin for orphaned objects seems like its going to cause maintenance/operation issues, can we alter the design to handle/avoid these scenarios?
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.
Objects not associate with workspace and do not have ACL defined, such objects can be considered "public", I think such objects won't require permission check. These saved objects behave like they are nowadays.
|
||
#### Where to store ACLs | ||
|
||
The ACL is a logically a sub-resource/attribute that is attached to OpenSearch Dashboards resources, and the same access control mechanism should apply to the ACL as the saved object it attaches to. We can either embed the ACL as attribute to the saved object, or store it separately as the standalone record, depending on what database is used by OpenSearch Dashboards. e.g. in the case of using NoSQL database as OpenSearch Dashboards metadata store, such as using OpenSearch index, embed the ACL into the saved object document as an attribute can simplify the privilege evaluation. while if using relational DB as OpenSearch Dashboards metadata store, storing ACLs as separate data records will be simpler. |
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.
If a user can 'write' to an object, it seems like they can alter its ACLs, this seems like a way to circumvent the permissions? Seems like the ACL associate needs to be protected from this level of access - otherwise anyone with a write allowed connection string is effectively a workspace super admin
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.
anyone with a write allowed connection string is effectively a workspace super admin
Yes, this is the current design. We only have read
and write
, and write
permission is currently the highest privilege, with write
permission, a user can delete the object.
I understand the permission model can go deeper and more complex, but we started with a simple one which serves our current use-cases and the upcoming use-cases which is under design. We try to avoid over design, you could see this as a trade-off(which is a practical choice I think ;))
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.
After sleeping on this design, a couple more ideas came to mind.
* Feature (API) access control is out of scope | ||
* Data (saved objects) access control is in scope | ||
|
||
## Design |
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 would be helpful to weight the recommended design against other approach(es), I see that this has been accounted for inline for key features and if there was a wholistic case made for another approach it would help illustrate the tradeoffs and benefits of your recommendation.
|
||
If a user only have read permission on the objects, they will be able to copy the object to an workspace they have access to. But this is not a typical “sharing”, as they make new object instances instead of really sharing the original objects. | ||
|
||
Given OpenSearch Dashboards saved objects has dependency hierarchy, such as dashboard depends on visualizations, and visualization in tern depends on index pattern. In any of the sharing cases, if a saved objects is shared, all its direct and transitive dependencies will also be shared. For example, if a dashboard is shared, then all the visualizations, index patterns that are used in the dashboard will be shared. |
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 clear that saved object inherit the permissions from the workspace, but if I attach ACL to a dashboard object, should visualizations and index patterns inherit dashboard object's ACL? Or the same ACL should attached to all visualization and index pattern objects specifically?
|
||
## Assumptions & Scopes | ||
|
||
* Authentication is out of the scope. We can assume the users are authenticated and user profile (user name and group info) has been injected into each request |
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.
While authentication is not in scope for this design - but there are plans to decouple authentication, lets add requirements on the current AuthN system expectations.
We've found internal features in the security plugin were actually being used as if they were part of a public interface, since this design depends on the security plugin accounting for these areas and making hard requirements will ensure no breaking changes and make migrating to the end-state Trinity authentication system more preditable.
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.
We've found internal features in the security plugin were actually being used as if they were part of a public interface
Could you share the example? Just want to make sure our implementation doesn't rely on security plugin internals, though I believe we're only using publicly accessible APIs.
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.
lets add requirements on the current AuthN system expectations.
What's only required is just as it describes: user profile (user name and group info) has been injected into each request
.
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.
Let's be thoughtful about communicating this features status in the security review process [1] since this feature security focused. There is a balance when communicating details, but as contributions to this feature will have impact on the security posture and the review process we should be prepared to handle those.
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.
Speaking of security reviews, I recommend starting the internal security review process early as this features complexity and risk potential is likely to require more lead time and time consuming activities.
|
||
### Is there any scaling issue of ACL-based access control? | ||
|
||
The ACL is attached to the data records. We will usually expect a few users/groups in the ACL, so the total user count should not be a scaling challenge |
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.
comment here related to scaling: #5084 (review)
@zengyan-amazon, I see that a pull request [1] has been initiated to implement parts of this design. I noticed there was a push for a review from the security plugin team, and there is substantial feedback on this document yet to be addressed, which could significantly impact the design. I understand this is your feature to build, and I genuinely appreciate the opportunity to provide feedback and guidance. However, it’s important to note that when feedback isn’t incorporated or addressed, it may deter me and my peers from engaging in future reviews. It’s crucial for the success of our collaborative efforts that we see tangible outcomes from the review process. Looking forward to seeing how this develops and hoping we can address the outstanding feedback for a robust design. |
|
||
For workspaces, a user may have following 3 type of permissions: | ||
|
||
* management |
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.
@zengyan-amazon It seems management
is not necessary in practice, it's basically write
+ library_write
, the library_write
give the user full access to all the saved objects associated with the workspace. The write
permission will give a user full access to a workspace object includes the ACLs on the object. To my understanding, this equals to management
, am I right?
@zengyan-amazon @gaobinlong @ruanyl @SuZhou-Joe Do we know the status of this? Can I assign someone responsible for responding to @peternied and for getting this merged or closed? |
Convert to draft due to no progress. |
Description
Add workspace access control design proposal
Issues Resolved
#4615
Check List
yarn test:jest
yarn test:jest_integration
yarn test:ftr