Open peternied opened 2 years ago
@dbwiddis I didn't get around to making a pull request into OpenSearch for an example, but for the moment I've been liking some concepts from Principal from java's implementation, here is what I was thinking:
public interface Principal {
/** Unique and immutable identifier */
public String name();
/** Returns true if this principle exists within the identity */
public boolean implies(final Identity ident);
}
In a use case inside an extension it could look like
public Response createResource(Request r) {
final ExtensionResource newResource = new ExtensionResource(...);
newResource.setOwner(r.getPrincipalIdentity());
// Other interesting things
return ...;
}
What do you think about this?
Initial Steps to follow:
there should be a payload that includes the identity of the current user
I'm trying to be precise and keep "identity" (logged in user) and "access" (permissions) separate.
Consider this scenario: User X (identity) authenticates (logs in) and OpenSearch determines them to have a role permitting access to Y data. They set up a scheduled job to do something with that data, and then they log out.
Now, later, the extension needs access to that data. There is no "identity" but the job still has permission to run.
I've been liking some concepts from Principal from java's implementation
This is probably the correct way to go from an interface, although most (all?) of the implementing classes look deprecated. But the concept of a Principal (user or unattended service) is good.
Initial Steps to follow:
- Extract user from Opensearch core, and Create a user identity with relevant info
Yes with the caveat that this isn't necessarily a user, it's a "principal" which may be a group, may be a non-user service object, etc.
- Add principal identifier to be able to pass it to the extension
Yes, although it may not be necessary to pass the entire principal identifier to the extension. If OpenSearch maintains a registry of these principals, all we need is a unique key passed to the extension; the extension needs only pass this same key back where OpenSearch can lookup the principal from the registry. See Phantom Token Approach or a variation, Split Token Approach. Replace "client" in those diagrams with "extension".
- Figure out how to handle this principal information inside extension
The extension doesn't need to know very much about what its token represents, it just needs to keep track of it and pass it back to OpenSearch, where OpenSearch will give it any necessary information, for example:
@peternied @DarshitChanpura initial thoughts, @dbwiddis covered most of it:
- Add principal identifier to be able to pass it to the extension
- Principal looks like a right way to encapsulate security information, my head goes around on how can we support extensions written in other languages.
I'm presuming they would have similar "classes" which deserialize the transport streams?
- This works for the extension when a resource is co-ordinated by OpenSearch and extension get's identity/access tokens to fetch information. As @dbwiddis said, there could be resources created by the extension without user context, how can we handle them ?
This is definitely a sticking point and we may want to get PM team involved in the trade-offs here. My thought is that we have a "service principal" (designated 'bot' account) with a restricted set of permissions; users would have more permissions (create/destroy, etc.) while the service principal would primarily just execute tasks.
I'm sure there are other ways to do it.
- How does it work when 2 extensions would like to communicate with each other?
I think we do not want to support/encourage that directly. That is briefly mentioned in #108, and while I don't think we need to take steps to prohibit inter-extension communication we should design the primary means to send information via OpenSearch. Originally I thought we could just register a REST API request from Extension A, that Extension B could call, but I understand that may not be directly possible right now.
- How does it work when 2 extensions would like to communicate with each other?
I think we do not want to support/encourage that directly.
:100: If extensions 'know' about one another, who is responsible for making sure they are communicating securely? I would recommend extension to extension communication should be done via standard OpenSearch APIs, extensions registered REST APIs, or plugin extensibility points that are all proxied through OpenSearch.
I think job scheduler is a little bit of a different scenario - what about anomaly detection extension creating data, and that data is processed by a machine learning extension - providing access to that data should be secured with constraints and limitations shared by the OpenSearch cluster's configuration.
We've got an issue dedicated to job scheduler like scenarios - https://github.com/opensearch-project/OpenSearch/issues/3850 that will be our focus after laying this groundwork
Extensions need to interact with external systems, but we cannot offer security protections around those systems. If someone passed an Azure Access token to a snapshot storage extension, they need to trust the extension's interactions with Azure are doing the right thing.
For the future, someone could build an Azure access security manager extension that vends access tokens to extensions that access Azure resources - which in turn would use OpenSearch to manage the access control to those resources.
When requests from OpenSearch -> Extension arrive there should be a payload that includes the identity of the current user. Given a request there should be a way to extract this information. When requests are made from Extension -> OpenSearch this information should be included.