raystack / guardian

Guardian is universal data access management tool with automated access workflows and security controls across data stores, analytical systems, and cloud products.
https://guardian.vercel.app/
Apache License 2.0
137 stars 21 forks source link

Guardian Approval through Slack #363

Closed utsav14nov closed 1 year ago

utsav14nov commented 1 year ago

Problem statement As an Approver for Guardian appeals, Users should be able to approve/reject appeal requests from slack itself.

Proposed solution There has to be an action button (Approve/Reject) along with the approval notification sent to slack, so the approver can take necessary action directly from slack. This will enable the approver to be able to approve/reject appeals even on mobile when they are not near a laptop.

Screenshots of existing and new notification

Existing Notification:

You have an appeal created by abc@gmail.com requesting access to play (bigquery: project:play) with role viewer. Appeal ID: 9890-ae8e421d5640

New Sample Notification with action Buttons:

Screenshot 2023-02-15 at 2 31 24 PM

After Either approve or Reject:

Screenshot 2023-02-15 at 3 08 46 PM

Changes recommended

  1. Slack notifier client should now support sending attachments/ blocks and buttons along with text in the notification messages.The block, button and metadata templates can be configured in env just like text is configured right now with the default value in Guardian.

    Example configuration:

    blocks = [
    {
        "type":"section",
        "text" : {
            "Type":"mrkdwn",
            "Text" : "You have a appeal created {{.appeal_id}}"
        }
    },
    {
        "type":"section",
        "fields" : [
            {
                "Type":"mrkdwn",
                "Text" : "*Provider:*\n{{.provider_type}}"
            },
            {
                "Type":"mrkdwn",
                "Text" : "**Resource Type:*\n{{.resource_type}}"
            },
        ]
    },
    {
        "type":"actions",
        "elements" : [
            {
                "Type":"button",
                "Text" : "Approve",
                "Value": "approved"
            },
            {
                "Type":"button",
                "Text" : "Reject",
                "Value": "rejected"
            }
        ]
    }
    ]

    metadata_fields : ["appeal_id","resource_name","approval_step","role","account_id"]

  2. Guardian should be able to handle actions made into slack i.e the Request Url configured in slack for actions has to be developed in Guardian. Following are the Some Proto/Handler changes recommended in Guardian:

Proto for Slack Action :

message  SlackActionRequest {
    message User {
        string Id = 1
        string Username = 2
    }
    message Action {
        string value = 1
    }
    message Message {
        map<string, string> EventPayload = 1
    }
    User user = 1
    Repeated Action actions = 2
    string responseUrl = 3
    Message message = 4
}

message  SlackActionResponse {
    string text = 1
    string responseType = 2
    string replaceOriginal = 3
}

Rpc HandleSlackAction(SlackActionRequest) returns (SlackActionResponse) {
    option(google.api.http) = {
        post: “v1beta1/fire_action”
        body: “*” 
    }
}

New Handler Path : api/handler/vibeta1/notifier.go

@bsushmith

bsushmith commented 1 year ago

@utsav14nov Let's have the endpoint in this way - v1beta1/notifier/<notifier-type>/execute where <notifier-type> = slack in this case

@rahmatrhd @mabdh @haveiss requesting for your comments.

mabdh commented 1 year ago

@bsushmith I am trying to understand, so what the new endpoint responsibility is? Is it being called when approve or reject button is clicked?

If yes, why not just using some appeal approval api ?

rahmatrhd commented 1 year ago
  1. how will the user authenticate to access the APIs?
  2. if slack can handle the authentication, we might as well treat the slack bot as a frontend client. And as @mabdh suggested, we can use the same approval API
utsav14nov commented 1 year ago

@mabdh @rahmatrhd

  1. We can configure only one request url in slack for an app where it post data on every button action in slack. It post data regarding what action is pressed, which user has clicked , from which channel it is requested and other metadata etc.
  2. Approve and Reject endpoints need appeal_id and approval_step in url which needs to be build on runtime and slack doesn't supports it.
  3. Also only one request url is configured for the one app, we cannot configure post url for each button in slack.
  4. Slack Request is authenticated by our application through X-Slack-Request-Timestamp header sent through slack. There is a logic provided by slack to create this secret at backend and compare. This make sure that the request is coming from the authenticated slack app.
  5. If above step is authenticated well, user slack id is provided in payload sent from slack which can be used to get email id of the user performed the action.
ravisuhag commented 1 year ago

+1 on using same approval APIs, we should treat these as clients, very similar to CLI.

mabdh commented 1 year ago

@utsav14nov can you also please share the link to the slack API that you refer to?

utsav14nov commented 1 year ago

As discussed over the call, we all agreed on only on change in guardian i.e. adding support to notification messages to also send blocks/attachments to format notification better (Point 1 of changes recommended in above issue). Rest flow will be taken care by separately other services.

cc: @mabdh @rahmatrhd @bsushmith

ravisuhag commented 1 year ago

@utsav14nov Can we update the issue with final approach we are taking. Which also summarises the decisions taken.

singhvikash11 commented 1 year ago

@utsav14nov @bsushmith @rahmatrhd slack API on Approve/Reject button/action could capture account_id and action, account_id is an alphanumeric value and not exists in IAM users nor in appeal tables. If we add a flag into the post body of existing approval like source=slack then we can change appeal Api to resolve the email id for a given account_id using slack Api and continue with the rest of the approval flow given email id exists in appeal tables.

bsushmith commented 1 year ago

@singhvikash11 one of the primary problems with the initial approach or using slack api directly was with respect to authentication.

Currently, guardian service is built in such a way that it expects authentication is already done before it receives the API call(primarily through shield), and it expects a specific header with authenticated user email which slack is unable to send. so instead of mingling the responsibilities here, the following approach can be taken -

The UI is out of scope for guardian changes and it will depend on how it will be implemented by different users. With this approach, it will be extensible for other notifier providers also if needed later.

@rahmatrhd @AkarshSatija @haveiss

rahmatrhd commented 1 year ago

@bsushmith @utsav14nov let's update the main thread's description with that approach