Trying to pass on RStudio connect API key using plumber

I'm trying to build a plumber API that uses a key provided in req$HTTP_AUTHORIZATION to access pinned data, but it seems like this information is not available when plumber is hosted on Rstudio connect.

Works locally but returns an empty list from Connect:

function(req) {
  return(req$HTTP_AUTHORIZATION)
}

Works on Connect

function(req) {
     return(req$postBody)
}

Raises an exception on Connect:

function(req) {
     return(as.list(req))
}

I'm assuming what's happening here is that the authorization is being suppressed by Connect which makes sense, but I'm wondering if this behaviour is documented anywhere? Is the best method for this kind of workflow to encrypt the key and send it as part of the body?

Tagging @Blair09M on this post

@gordon you're correct that the Authorization header is being sanitized by RStudio Connect and is not being passed to Plumber. There are a couple of options that I can think of in this scenario:

  1. Requiring authorization for both the API call and then forwarding that authorization to the pin request makes sense if you have users who may be able to access the API but not access the pin. However, I'm imagining that users who have access to the API should also have access to the pinned data. In this case, you could still require authentication for the API (require the Authorization header) but then embed an API key in the Plumber API as an environment variable (via RStudio Connect) to provide access to the pinned data. In this way, users would make requests to the API with their own API keys, but then requests for the pinned data would all use the same API key that you provide as an environment variable.
  2. If option 1 doesn't work, you could pass the API key with the required Authorization header and pass it in another header (like key) with requests made to the API. This secondary header containing the API key would be passed to Plumber and could be used from within the API process to request the pinned dataset.

In my opinion, option 2 should only be necessary if you are trying to restrict the API and the pinned data independent of one another within the API process. If you assume that anyone with the ability to use the API should also be able to access the pin, option 1 makes more sense.

2 Likes

Thanks!

We have some pinned data that's only visible to particular users, but we want a single API which lets all users perform actions on the data that they have access to. The reason for this is that the data access is maintained at the pin level while the API is available to everyone. But I'll just pass the api key as another header, that's a great idea.

1 Like