rill icon indicating copy to clipboard operation
rill copied to clipboard

Security policy without measures should not fire certain API requests

Open ericpgreen2 opened this issue 1 year ago • 5 comments

If you create a security policy that only includes dimension fields, but not any measure fields, it:

  1. Makes a /timeseries request, which fails because there are no measure names
  2. Makes /aggregation requests with an empty sort key
  3. Makes a request for /resource?name.kind=rill.runtime.v1.ProjectParser&name.name=parser, which fails because restricted users don’t have access to parse errors
security:
  access: true
  include:
    - if: true
      names: [company, plan_name]

Screenshot 2024-07-08 at 18 45 24

ericpgreen2 avatar Jul 09 '24 13:07 ericpgreen2

Could you record a repro for me to get to the screenshot state? @ericpgreen2

After adding the codeblock to rill.yaml

security:
  access: true
  include:
    - if: true
      names: [company, plan_name]

I can't seem to view the error requests as mentioned in the screenshot.. Here's what I have

https://github.com/user-attachments/assets/2b6af5bb-5972-4b0c-897c-357c693e24dd

lovincyrus avatar Aug 12 '24 21:08 lovincyrus

Yeah, the key is adding the codeblock to the metrics view, not rill.yaml. Here's one way to reproduce:

  1. Clone our example partner-filtered dashboard project
  2. Replace the security policy of the first dashboard (a_admin_access.yaml) with the above code snippet. Here's the edited file in full:
    # a_admin_access.yaml
    # Visit https://docs.rilldata.com/reference/project-files to learn more about Rill project files.
    
    title: Admin-level access
    type: metrics_view
    model: margins_model
    timeseries: __time
    measures:
      - name: total_cost
        label: "Total Cost"
        expression: "SUM(cost)"
        description: "The sum of cost"
        format_preset: currency_usd
      - name: total_revenue
        label: Total Revenue
        expression: SUM(revenue)
        description: The sum of revenue
        format_preset: currency_usd
      - name: net_revenue
        label: "Net Revenue"
        expression: "SUM(revenue) - SUM(cost)"
        description: "The sum of revenue minus the sum of cost"
        format_preset: currency_usd
      - name: margin
        label: "Margin"
        expression: "(SUM(revenue) - SUM(cost))/SUM(revenue)"
        description: "Net revenue divided by sum of revenue"
        format_preset: percentage
      - name: unique_customers
        label: "Unique Customers"
        expression: "COUNT(DISTINCT company)"
        description: "The count of unique companies"
        format_preset: humanize
    dimensions:
      - name: company
        expression: company
        label: Company
        description: "The name of the company"
      - name: plan_name
        expression: plan_name
        label: Plan Name
        description: "The name of the billing plan"
      - name: location
        expression: "location"
        label: "Cost by Region"
        description: "The region incurring costs"
      - name: component
        expression: component
        label: Cost by Component
        description: "The component generating costs"
      - name: app_name
        expression: "app_name"
        label: "Cost by App Name"
        description: "The app generating costs"
      - name: sku_description
        expression: "sku_description"
        label: "Cost by SKU"
        description: "The sku description for costs"
      - name: pipeline
        expression: "pipeline"
        label: "Cost by Data Pipeline"
        description: "The pipeline incurring costs"
      - name: environment
        expression: "environment"
        label: "Cost by Environment"
        description: "The environment incurring costs"
    available_time_zones:
      - America/Los_Angeles
      - America/Chicago
      - America/New_York
    security:
      access: true
      include:
        - if: true
          names: [company, plan_name]
    
  3. Preview the dashboard, and "View as" [email protected]
  4. Observe the broken state image

ericpgreen2 avatar Aug 13 '24 14:08 ericpgreen2

Makes a request for /resource?name.kind=rill.runtime.v1.ProjectParser&name.name=parser, which fails because restricted users don’t have access to parse errors

What should be the expected action item? Do we want to allow restricted users to access and parse the errors? @ericpgreen2

lovincyrus avatar Aug 14 '24 19:08 lovincyrus

Makes a request for /resource?name.kind=rill.runtime.v1.ProjectParser&name.name=parser, which fails because restricted users don’t have access to parse errors

This is a pretty tricky case. For context, we currently support a couple things:

  1. In Rill Developer, when editing project files in an external IDE, we support "hot reloading". External edits are instantly reflected in the dashboard. When there’s a parse error, we say so.
  2. In Rill Cloud, when a dashboard becomes invalid, rather than show an error (e.g. a 404), we show the “last valid” dashboard. Consequently, for both Rill Developer and Rill Cloud, even if there's an error in the dashboard file, the dashboard resource is retained.

Do we want to allow restricted users to access and parse the errors?

I don't think so. For "real" restricted users, that'd be a security hole. For "mock" restricted users, I think it'd be conceptually confusing to grant them artificial privileges.

What should be the expected action item?

Here's one idea:

  1. Rather than showing a full-screen "Error parsing dashboard" message, we: a. At the top of the page, show a red error banner that says "Error parsing dashboard – you are viewing your last valid dashboard specification" b. Display the "last valid dashboard", like we do in Cloud. This would actually be an accurate representation of what would happen if the user committed their changes.
  2. Only for project admins do we show the error banner (and request the project parser). I.e.: a. When there's no mock user b. When the mock user is a project admin

ericpgreen2 avatar Aug 15 '24 10:08 ericpgreen2

At the top of the page, show a red error banner that says "Error parsing dashboard – you are viewing your last valid dashboard specification"

Hey @jkhwu, do we currently use any error banner atm?

If not, I was thinking of placing the error banner here:

Image

Update: can refer to https://www.figma.com/design/Qt6EyotCBS3V6O31jVhMQ7/RILL?node-id=144-815&t=AYrXdJOOdMJ4KUmx-0

lovincyrus avatar Aug 16 '24 20:08 lovincyrus

Rather than showing a full-screen "Error parsing dashboard" message, we: a. At the top of the page, show a red error banner that says "Error parsing dashboard – you are viewing your last valid dashboard specification" b. Display the "last valid dashboard", like we do in Cloud. This would actually be an accurate representation of what would happen if the user committed their changes.

Are you referring to the banner triggered from the event bus or the RepresentingUserBanner?

lovincyrus avatar Sep 05 '24 17:09 lovincyrus

Are you referring to the banner triggered from the event bus or the RepresentingUserBanner?

The one controlled by the event bus + BannerCenter. I'd have preferred the RepresentingUserBanner to also have been controlled via event bus + BannerCenter.

ericpgreen2 avatar Sep 05 '24 17:09 ericpgreen2

Only for project admins do we show the error banner (and request the project parser).

To confirm, are you referring to a user who can manage projects or a mock user who is an admin?

lovincyrus avatar Sep 05 '24 18:09 lovincyrus

To confirm, are you referring to a user who can manage projects or a mock user who is an admin?

Both of them :)

ericpgreen2 avatar Sep 05 '24 18:09 ericpgreen2