Skip to content
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

[META] Authorization in the REST layer #2590

Closed
15 tasks done
Tracked by #3352
cwperks opened this issue Mar 27, 2023 · 0 comments
Closed
15 tasks done
Tracked by #3352

[META] Authorization in the REST layer #2590

cwperks opened this issue Mar 27, 2023 · 0 comments
Assignees
Labels
triaged Issues labeled as 'Triaged' have been reviewed and are deemed actionable. v2.11.0 Issues targeting the 2.11 release

Comments

@cwperks
Copy link
Member

cwperks commented Mar 27, 2023

REST Requests destined for extensions never hit the Transport-layer of OpenSearch and are forwarded to the extension via the registered Rest handler in the REST Controller. In the current model of security, authorization is performed on authenticated requests via the action filter extension point and is run just-in-time before the action itself is executed on a Node.

This will not work for extensions. A new authz layer must be built within the REST handler wrapper (SecurityRestFilter) to block REST request forwarding to extensions for unauthorized requests.

Resolves:

  • As a user, using basic http auth, my requests to extensions are controlled based on my permissions
  • As a developer I can define the roles/permissions required in order to access my extension and my extension's APIs.
  • As an extension developer, I can check a user's permission for resources managed by my extension
  • As a user, when I run an extension I do not have to worry about it accessing data and configurations on the cluster to which it should not have permissions.
  • As a user, when I run an extension, it should not allow me to access data and configurations on the cluster which I do not have permissions for.

Questions

List of items to complete

Documentation


Background:

As part of ongoing effort to migrate plugins as extensions, it is essential that the end-user experience related to security remains the same. To ensure this, a solution needs to be implemented to put authorization checks into effect for extensions and associated requests.

Problem:

Current security model enforces authorization checks at Transport Layer. There is no authorization mechanism in place at REST Layer. Since Extensions will not communicate with the cluster at Transport Layer, it is essential to implement some form of authorization to apply security.

In order to implement this new model, following needs to be addressed:

  1. How can we authorize user requests REST requests for extensions? How will security be enforced in following scenarios?(Assuming that the cluster has Anomaly Detection extension installed,.)
    1. Scenario: (User has required permissions)
      1. User A has permissions to “cluster:admin/opendistro/alerting/monitor” defined in security plugin.
    2. Scenario: (User doesn’t have required permissions)
      1. User B does not have permissions to “cluster:admin/opendistro/alerting/monitor” .
    3. Scenario: (User has correct permissions but extensions does not have required permission)
      1. User C has required permission “cluster:admin/opendistro/alerting/monitor” and also access to the endpoint /createDetector. However, extension doesn’t have required permission to write anything to its index.
    4. Scenario: (User has smaller set of permissions than extensions)
      1. User D has cluster:admin/opendistro/alerting/monitor/search , but somehow has permission to /createCluster . AD extension has full permission cluster:admin/opendistro/alerting/monitor/* .

Note: AD extension has .. permission is liberally used in the scenario descriptions,. In the actual implementation, a service account will be used “on-behalf-of” extension. And extension will also send “on-behalf-of” user token, but this will be covered separately.

Proposed solutions:

Option 1: No authorization
This option is completely non-viable because:

  • extensions actions will not be authorized (a free-roam system with no boundaries)
  • It wiill be a downgrade in security model

Option 2: Extensions to have their own authorization model

This option is non-viable because we would to establish trust boundaries. Everything outside the OpenSearch process is untrusted, and extensions will be outside OpenSearch process.

  • Extensions by default are untrusted entities. So no authorization decisions made by extensions should be trusted.

Option 3: Perform AuthZ checks at REST layer (Recommended)

  • This implementation will allow all incoming request to be authorized before they are handed over to ActionHandler. (This step was previously done at Transport Layer before action execution)

Option 3a: Perform extensions specific AuthZ checks at REST layer, everything else at Transport Layer.

  • Decent work, more complicated implementation
  • Potential risk of actions not being checked at all
  • Pros: TBD
  • Cons: TBD

Option 3b: Duplicate AuthZ check in REST layer as well. This will run checks twice.

  • Decent work
  • Might be slow
  • No change to existing workflow
  • Pros: TBD
  • Cons: TBD

Option 3c: Move AuthZ check from Transport layer to REST layer during API request handling

  • Most work, most viable option in long-term, authz checks happen once only
  • Current workflow will no longer exist
  • What should happen to the checks that happen at Transport layer?
  • What actions will no longer be checked?
  • Pros: TBD
  • Cons: TBD

Diagrams and Visualizations

Current Implementation

Current implementation model doesn’t have a concept of extensions associated.

sequenceDiagram
    actor Client;
    participant OpenSearch;
    participant SecurityRestFilter;
    participant SecurityInterceptor;
    participant Action Handler as Action Handler;

    Client->>OpenSearch: Request
    OpenSearch->>SecurityRestFilter: REST Request Received
    SecurityRestFilter->>SecurityRestFilter: If using client cert, AuthN
    SecurityRestFilter-->>OpenSearch: Continue request
    OpenSearch->>SecurityInterceptor: Transport Request Received
    SecurityInterceptor->>SecurityInterceptor: AuthN user via internal / external auth providers
    SecurityInterceptor->>SecurityInterceptor: Resolve AuthZ for user
    SecurityInterceptor-->>OpenSearch: Allow / deny request
    OpenSearch->>Action Handler: Send transport request to action handler
    Action Handler-->>OpenSearch: Result
    OpenSearch->>Client: Response
Loading

New Implementation

This diagram follows the setup of moving AuthZ checks up into REST Layer. There will not be any new interactions with Transport Layer.

sequenceDiagram
    actor Client;
    participant OpenSearch;
    participant SecurityRestFilter;
    participant SecurityInterceptor;
    participant Action Handler as Action Handler;

    Client->>OpenSearch: Request
    OpenSearch->>SecurityRestFilter: REST Request Received
    rect rgba(60, 0, 0, .3)
    SecurityRestFilter->>SecurityRestFilter: AuthN via client cert / internal / external providers
    SecurityRestFilter->>SecurityRestFilter: Resolve AuthZ for user
    SecurityRestFilter-->>OpenSearch: Allow / deny request
    end
    OpenSearch->>SecurityInterceptor: Transport Request Received
    SecurityInterceptor->>SecurityInterceptor: AuthN via internal / external providers
    SecurityInterceptor->>SecurityInterceptor: Resolve AuthZ for user
    SecurityInterceptor-->>OpenSearch: Allow / deny request
    OpenSearch->>Action Handler: Send transport request to action handler
    Action Handler-->>OpenSearch: Result
    OpenSearch->>Client: Response
Loading
  • Pros:

    • Performs complete authz check for all requests (from user and extensions)
  • Cons:

    • Doesn’t do early authz check before forwarding user request to extensions. Might result in extra bandwidth as all request will forwarded to extension nodes.
  • Improvement:

    • Add an extra step to check whether user’s access is checked against requested endpoint extension endpoint.

New Request Flow

---
title: API Request Flow
---
flowchart TB
    Request((Request)) --> |An API Request is received Opensearch| OpenSearch
    OpenSearch --> |Identifies the handler to be called| RestController
    RestController --> |Request is meant for core| BaseRestHandler
    RestController --> |Request is meant for extension| ExtensionRestHandler
    BaseRestHandler & ExtensionRestHandler --> |Before handler is invoked, <br> request is intercepted by wrapper| Wrapper
    Wrapper --> |Perform authentication & authorization at REST Layer| Check{AuthN-AuthZ check}
    Check --> |Failure, 403 Unauthorized| Response((Response))
    Check -->|Success, proceed with original rest handler| OriginalRestHandler
    OriginalRestHandler --> |Process the request and form the response| OriginalRestHandler
    OriginalRestHandler --> |Return the response, 200 OK| Response

Loading
@github-actions github-actions bot added the untriaged Require the attention of the repository maintainers and may need to be prioritized label Mar 27, 2023
@stephen-crawford stephen-crawford added triaged Issues labeled as 'Triaged' have been reviewed and are deemed actionable. and removed untriaged Require the attention of the repository maintainers and may need to be prioritized labels Mar 27, 2023
@peternied peternied added the v2.10.0 Issues targeting release v2.10.0 label Aug 9, 2023
@davidlago davidlago added v2.11.0 Issues targeting the 2.11 release and removed v2.10.0 Issues targeting release v2.10.0 labels Aug 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
triaged Issues labeled as 'Triaged' have been reviewed and are deemed actionable. v2.11.0 Issues targeting the 2.11 release
Projects
Status: 2.11.0 - (Launched)
Status: Done
Development

No branches or pull requests

5 participants