Recommendations for encrypting auth headers

Imported Google Group message. Original thread at: Redirecting to Google Groups Import Date: 2016-01-19 21:42:26 +0000.
Sender:Anthony Ferrara.
Date:Thursday, 7 January 2016 22:50:24 UTC.

Hey everyone.

We’re currently evaluating using Tyk as a gateway of a greenfield project that we’re working on. One of the assumptions that we’re using is that we have no server-side clients. The only clients are a single-page application and mobile. So we’d like to use OAuth2 for authentication.

However, to use OAuth2 securely for a single-page-app requires some interesting compromises. We were investigating using a proxy: http://alexbilbie.com/2014/11/oauth-and-javascript/

The basic idea is to store the bearer token and refresh token in an encrypted cookie that the single page application uses to communicate with the API. The proxy then decrypts the cookie and decorates the request with the appropriate headers. So to the API gateway, it looks like any other OAuth2 request. The proxy would also manage the refresh functionality transparently, and decorate the response with set-cookie as necessary.

One idea that came to mind would be to not build a proxy, but to add this functionality to the Tyk instance as a plugin. This comes with some interesting questions though.

  1. Support for and performance of crypto primitives.

    A library may fill this need

  2. Lack of crypto secure random number source in JS (crypt/rand is not exposed to JS)

    A patch to Tyk may be required to fill this need…

However, there are two far more serious questions:

  1. Right now, it doesn’t appear that there’s a way to decorate or modify the return of the HTTP request that’s proxied (meaning that the “middleware” isn’t really middleware but a hook that happens before the request).

    This means that setting an encrypted cookie would be impossible, since we can’t modify the response that’s sent back.

  2. It doesn’t appear there’s a way to “capture” and resubmit a request.

    So if the token is invalid, there’s no way to capture that error, update the token and then retry the request.

This seems like a blocker to this approach.

Is there something obvious I’m missing here? Is there a better approach to this that doesn’t require us to use two authentication methods or two proxies (an “id” proxy, and an “api” proxy)?

Thanks!

Anthony

Imported Google Group message.
Sender:Martin Buhr.
Date:Friday, 8 January 2016 09:28:50 UTC.

Hi Anthony,

Thanks for trying Tyk :slight_smile:

First off, I think there’s simpler approaches you could look at:

For SPA and mobile apps using OAuth there is the implicit (access token) grant type, this type assumes that the authenticating client’s source code is publicly viewable and therefore a client secret can be compromised. The implicit grant type will essentially only provide a bearer access token to the authorised party without a refresh token, the token is only valid for a few hours too (one hour by default). The idea being that tokens are requested regularly from insecure clients and require re-authentication to get a new one.

Tyk supports the access token grant so it’s quite easy to implement without modification.

Another option you have is to use JSON Web Tokens, these can offer quite a good degree of trusted security with insecure clients, the flow goes something like this:

  • User logs into your app
  • App creates a token ID with a public RSA key in Tyk using it’s REST API
  • App generates signed JWT (with respective user data and claims) using secure private key server-side
  • App returns JWT to client

The client now has a token that is cryptographically signed (by a secure private key), that also contains any user-id, permissions and other claims embedded in a secure data structure. When Tyk sees that token, it will verify the signature, and if the token has been modified in any way (e.g. to escalate permissions) the signature will be invalid, therefore rejecting the request.

Again Tyk supports this out of the box.

You could go a step further and embed the claims for the key in the meta data of the key within Tyk, and then have Tyk write them to the headers that your upstream application sees, this makes it easier to extract user ID info instead of decoding the token. It’s also quite performant.

The second thing I’d say is regarding your idea of a cookie - if you are building a RESTFul API, then cookies are not usually recommended as you want to avoid any idea of state (opinion seems to be split on this). Nonetheless, cookies will limit your API if in the future you are looking to build non-JS clients that do not have strong cookie support, since cookies enforce the idea of a session and therefore would require an API client using your service for RPC to store session cookies across it’s infrastructure to make requests, or constantly authenticate if requests happen in parallel across machines.

(Tyk does support authentication via cookie out of the box)

If you really want to use the cookie method, and have the gateway intercept requests, modify them and then pass them on, you would probably need to write a custom middleware module for Tyk in Go, not JS. This is pretty easily achieved as middleware is interface-based, and crypto primitives in Go are built-in, proven, and fast when compared to JS (especially JS running in a sandbox VM!).

The other benefit is that you have access to the request writer itself and can drop cookies, as opposed to the JS middleware which is mainly there to enrich data or communicate with additional services outside the scope of Tyk’s built-in features.

However, I’d urge you to look at the JWT approach as it’s far more secure than the implicit grant, Google actually mix the two, they have an OAuth flow that generates a JWT (it’s an idea we quite like, so might make it’s way into our codebase soon).

Hope that helps,

Cheers,
Martin