Skip to content

Instantly share code, notes, and snippets.

@BigAB
Created June 29, 2016 05:26
Show Gist options
  • Save BigAB/465769c9e5647374e1462849ec8fd3e1 to your computer and use it in GitHub Desktop.
Save BigAB/465769c9e5647374e1462849ec8fd3e1 to your computer and use it in GitHub Desktop.
JWT Issuer Architecture Idea

Another Idea for JWT Issuer Architecture

Thinking about how to secure the refresh-token for the web gave me an idea for what I think would be a pretty good set up for issueing JWT access-tokens and refresh-tokens.

What if...

refresh-tokens are issued by a central stateful server (backed by a DB), that maintains a black list.

  • black list occasionally runs a "job" to remove any entries that have expired, keeping it light and lean
  • refresh-tokens are only available at a specific domain, so that we can use secure cookies for the web

access-tokens are issued where ever you want (non centralized, only need a secret).

  • have a small TTL (< 30mins)
  • can be used across domains
  • can be obtained with either a username:password pair, ssh-key, OR a valid refresh-tokens
  • when an access token is obtained using either username:password or ssh-key, a request is made also made for a refresh-token, passing the credentials and proxying the response (along with secure, httpOnly cookies) which should contain the refresh-token
  • do in fact have their scopes stored in the token

Here's the interesting twist: ** Refresh tokens are somewhat useless on their own, but require being paired with a valid, but possibly "recently-expired", access-token (what constitutes "recently-expired" should be configurable), to get a NEW access-token. **

When an API call is failed due to expired-auth, if a refresh-tokens is available, a request for a new access-token is made on behalf of the user, passing along the expired access-token, and if successful and a new access-token is provided, the original request is made again with the new access-token.

If there is no refresh-tokens provided, or the refresh-tokens has expired, the request fails and the user is "logged out" (both refresh token and access-token are purged), and will need to re-authenticate with a username:password pair or ssh-key.

refresh-tokens must be stored securely, for the platform, as they basically allow eternal access-tokens.

For the web, refresh tokens are stored in secure and httpOnly cookies, inaccessible from JavaScript (and XSS), but ultimately useless without an access token (even an "recently-expired" one), since CSFR attacks don't allow you to get the response (as far as I understand) from the access-token issuer, your only concern would be the concerns that have alway been there: a successful XSS attack could allow access for as long as the access-token was valid (mitigated a bit by short TTL), and any changes in scope would only take affect after the current access token expired (as access-tokens can't be revoked like refresh-tokens can).

Maybe this could even be modified to have API endpoints always issue a new token on every successfully authenticated request, limiting the scope problem to one request rather than a half-an-hour.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment