<p><div><div><div><div data-show-faces="false" data-height="21" data-width="100" data-layout="button_count" data-send="true" data-href="https://www.r-bloggers.com/slack-and-plumber-part-two/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="https://rviews.rstudio.com/2018/11/27/slack-and-plumber-part-two/"> R Views</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>This is the final entry in a three-part series about the <a rel="nofollow" href="https://www.rplumber.io/" target="_blank"><code>plumber</code></a> package. <a rel="nofollow" href="https://rviews.rstudio.com/2018/08/30/slack-and-plumber-part-one/" target="_blank">The first post</a> introduces <code>plumber</code> as an R package for building REST API endpoints in R. <a rel="nofollow" href="https://rviews.rstudio.com/2018/08/30/slack-and-plumber-part-one/" target="_blank">The second post</a> builds a working example of a <code>plumber</code> API that powers a <a rel="nofollow" href="https://api.slack.com/slash-commands" target="_blank">Slack slash command</a>. In this final entry, we will secure the API created in the previous post so that it only responds to authenticated requests, and deploy it using <a rel="nofollow" href="https://www.rstudio.com/products/connect/" target="_blank">RStudio Connect</a>.</p>
<div>
<img src="https://i1.wp.com/rviews.rstudio.com/post/2018-11-20-blair-plumber-slack-part-two-files/plumber-slack-demo.gif?w=456&ssl=1" data-recalc-dims="1">
</div>
<p>As a reminder, this API is built on top of simulated customer call data. The slash command we create will allow users to view a customer status report within Slack. This status report contains customer name, total calls, date of birth, and a plot of call history for the past 20 weeks. The simulated data, along with the script used to create it, can be found in the <a rel="nofollow" href="https://github.com/sol-eng/plumber-slack" target="_blank">GitHub repository</a> for this example.</p>
<div>
<h2>Setup</h2>
<p>Successfully following this example assumes you have created a <a rel="nofollow" href="https://slack.com/" target="_blank">Slack</a> account and you have <a rel="nofollow" href="https://api.slack.com/slack-apps" target="_blank">followed the instructions for creating an app</a>. The Plumber API as it currently exists is described in detail in the <a rel="nofollow" href="https://rviews.rstudio.com/2018/08/30/slack-and-plumber-part-one/" target="_blank">previous post</a>.</p>
<p>This API can be run through the UI as previously described, or by running <code>plumber::plumb(&quot;plumber.R&quot;)$run(port = 5762)</code> from the directory containing the API defined in <code>plumber.R</code>. As it stands now, this API could be deployed and used by Slack. However, it’s important to remember that we have no control over the request that Slack makes to the API. Because of this, we can’t rely on RStudio Connect’s <a rel="nofollow" href="http://docs.rstudio.com/connect/admin/content-management.html#api-keys" target="_blank">built-in API authentication mechanism</a> to secure the API because there is no way to submit a key with the request. Our options are either to expose the API with no security, meaning anyone can access the endpoints we’ve defined, or to find some other mechanism for securing the API so that it only responds to authorized requests.</p>
</div>
<div>
<h2>API Security Patterns</h2>
<p>The <a rel="nofollow" href="https://www.rplumber.io/docs/security.html" target="_blank"><code>plumber</code> documentation</a> provides a good introduction to API security for the R user:</p>
<blockquote>
<p>The majority of R programmers have not been trained to give much attention to the security of the code that they write. This is for good reason since running R code on your own machine with no external input gives little opportunity for attackers to leverage your R code to do anything malicious. However, as soon as you expose an API on a network, your concerns and thought process must adapt accordingly.</p>
</blockquote>
<p>API security can be challenging to address. As it stands today, it is the developer’s responsibility to provide proper security on API endpoints, though in the future, there may be additional security features added to <code>plumber</code> or available via other R packages.</p>
<p>As mentioned in the <a rel="nofollow" href="https://www.rplumber.io/docs/security.html" target="_blank"><code>plumber</code> documentation</a>, there are a number of things to consider when designing API security. For example, if the API is deployed on an internal network, securing the API may not be as important as it would be if the API was publicly exposed on the internet. When an API needs to be secured, there are several potential attack vectors that need to be handled. In this specific example, we are exposing a public endpoint that provides access to sensitive customer data. If we are unable to authenticate incoming requests, then we risk exposing sensitive data. To prevent this data from falling into the wrong hands, we will focus on verifying incoming requests so that the API only responds to requests made from Slack.</p>
<p>There are several different methods for authenticating requests made to API endpoints. One common method is the use of API keys, which are cryptographically secure values sent with the request to verify the identity of the client. However, in this case, we have no control over the request Slack sends, so we cannot include such a key in the request. Thankfully, Slack has provided an alternative authentication method using <a rel="nofollow" href="https://api.slack.com/docs/verifying-requests-from-slack" target="_blank">signed secrets</a>. Full details can be read in the Slack documentation, but in essence, each Slack application is assigned a unique secret value that, when used in connection with other request details, can be used to verify that an incoming request is indeed coming from Slack and not an unknown third party.</p>
</div>
<div>
<h2>Securing the API</h2>
<p>In order to secure our API so that only requests from Slack are honored, we first need to obtain the signing secret for our application. This value can be found in the Basic Information section of the Slack application settings. Now, it is important to remember that this is called a signing secret for a reason: it should not be shared with anyone. To avoid exposing this secret, we can save it as an environment variable. We add this in a current R session by using <code>Sys.setenv(SLACK_SIGNING_SECRET = </code></div>