diff --git a/atlassian-connect-core.cabal b/atlassian-connect-core.cabal
--- a/atlassian-connect-core.cabal
+++ b/atlassian-connect-core.cabal
@@ -1,11 +1,11 @@
 cabal-version: 1.12
 
--- This file has been generated from package.yaml by hpack version 0.34.2.
+-- This file has been generated from package.yaml by hpack version 0.34.4.
 --
 -- see: https://github.com/sol/hpack
 
 name:           atlassian-connect-core
-version:        0.9.0.0
+version:        0.9.0.1
 synopsis:       Atlassian Connect snaplet for the Snap Framework and helper code.
 description:    This library allows you to quickly get an Atlassian Connect application running
                 on top of the Snap Framework. It provides best practices and helper functions to get you moving
@@ -76,7 +76,7 @@
     , http-client-tls >=0.2
     , http-media ==0.8.*
     , http-types >=0.8
-    , jwt >=0.6 && <0.8
+    , jwt ==0.10.*
     , mtl ==2.*
     , network-api-support >=0.2
     , snap >=0.14
diff --git a/src/Snap/AtlassianConnect/HostRequest.hs b/src/Snap/AtlassianConnect/HostRequest.hs
--- a/src/Snap/AtlassianConnect/HostRequest.hs
+++ b/src/Snap/AtlassianConnect/HostRequest.hs
@@ -153,7 +153,15 @@
 generateJWTToken :: CD.PluginKey -> P.POSIXTime -> T.Text -> StdMethod -> URI -> T.Text -> Maybe T.Text
 generateJWTToken pluginKey' fromTime sharedSecret' method' ourURL requestURL = do
   queryStringHash <- QSH.createQueryStringHash method' ourURL requestURL
-  return $ JWT.encodeSigned JWT.HS256 (JWT.secret sharedSecret') (createClaims pluginKey' fromTime queryStringHash)
+  return $ JWT.encodeSigned signer header (createClaims pluginKey' fromTime queryStringHash)
+  where
+      signer = JWT.hmacSecret sharedSecret'
+      header = JWT.JOSEHeader
+        { JWT.alg = Just JWT.HS256
+        , JWT.kid = Nothing
+        , JWT.typ = Nothing
+        , JWT.cty = Nothing
+        }
 
 createClaims :: CD.PluginKey -> P.POSIXTime -> T.Text -> JWT.JWTClaimsSet
 createClaims (CD.PluginKey pluginKey) fromTime queryStringHash = JWT.JWTClaimsSet
@@ -164,7 +172,7 @@
     , JWT.aud = Nothing
     , JWT.nbf = Nothing
     , JWT.jti = Nothing
-    , JWT.unregisteredClaims = M.fromList [("qsh", String queryStringHash)] 
+    , JWT.unregisteredClaims = JWT.ClaimsMap $ M.fromList [("qsh", String queryStringHash)]
     }
     where
         expiryTime :: P.POSIXTime
diff --git a/src/Snap/AtlassianConnect/OAuth.hs b/src/Snap/AtlassianConnect/OAuth.hs
--- a/src/Snap/AtlassianConnect/OAuth.hs
+++ b/src/Snap/AtlassianConnect/OAuth.hs
@@ -9,7 +9,7 @@
 Stability   : experimental
 
 By default, all HTTP requests that your add-on makes to an Atlassian application (like JIRA or Confluence) will
-be performed as your add-on user. For example, if your add-on service makes a HTTP request to comment on a JIRA 
+be performed as your add-on user. For example, if your add-on service makes a HTTP request to comment on a JIRA
 issue then the comment will be made as your add-on. However, if your addon requests the "ACT_AS_USER" scope then
 is is capable of using the OAuth service to generate an "access token" for a particular user on a tenant. This
 access token can be used to make make HTTP requests from your add-on service to an Atlassian product as a user
@@ -20,7 +20,7 @@
 
 You can read more about access token on the <https://developer.atlassian.com/cloud/jira/platform/oauth-2-jwt-bearer-token-authorization-grant-type/ official documentation>.
 -}
-module Snap.AtlassianConnect.OAuth 
+module Snap.AtlassianConnect.OAuth
     ( requestAccessToken
     , AC.AccessTokenResponse(..)
     , AC.AccessToken
@@ -50,15 +50,15 @@
 import qualified Snap.AtlassianConnect.Tenant          as AC
 import qualified Web.JWT                               as JWT
 
--- | Request an access token for a tenant and user with the requested scopes. 
--- 
+-- | Request an access token for a tenant and user with the requested scopes.
+--
 -- This token will allow you to post subsequent HTTP requests using the Snap.AtlassianConnect.HostRequest module
 -- as an impersonated user.
 --
--- The access token that is returned should be reused as much as possible in order to avoid hitting rate limits 
+-- The access token that is returned should be reused as much as possible in order to avoid hitting rate limits
 -- from the token generation service. Each token is specific to the tenant, user and scopes that
 -- it was created for. This means that the token reuse must be tenant, user and scopes specific.
-requestAccessToken 
+requestAccessToken
     :: AC.Tenant -- ^ The tenant to generate the Access Token for.
     -> UserKey -- ^ The user key of the user on the tenant that should be impersonated.
     -> Maybe [D.ProductScope] -- ^ The collection of scopes that will be used for impersonation. Providing none requests all scopes that the add-on provides.
@@ -79,7 +79,7 @@
         url = authBaseUrl `T.append` "/oauth2/token"
 
         formParams :: T.Text -> [(BSC.ByteString, BSC.ByteString)]
-        formParams assertion = 
+        formParams assertion =
             [ ("grant_type", "urn:ietf:params:oauth:grant-type:jwt-bearer")
             , ("assertion", T.encodeUtf8 assertion)
             ] ++ scopeParam
@@ -88,7 +88,7 @@
             Nothing -> []
             Just scopes -> (: []) . (,) "scope" . BSC.intercalate " " . fmap printScope . filter ((/=) D.ActAsUser) $ scopes
 
-printScope :: D.ProductScope -> BSC.ByteString 
+printScope :: D.ProductScope -> BSC.ByteString
 printScope D.Read         = "READ"
 printScope D.Write        = "WRITE"
 printScope D.Delete       = "DELETE"
@@ -102,9 +102,15 @@
     currentTime <- P.getPOSIXTime
     case generateAssertionClaims currentTime tenant userKey of
         Nothing -> return Nothing
-        Just claims -> return . Just $ JWT.encodeSigned JWT.HS256 jwtSecret claims
+        Just claims -> return . Just $ JWT.encodeSigned signer header claims
     where
-        jwtSecret = JWT.secret . AC.sharedSecret $ tenant
+        signer = JWT.hmacSecret . AC.sharedSecret $ tenant
+        header = JWT.JOSEHeader
+            { JWT.alg = Just JWT.HS256
+            , JWT.kid = Nothing
+            , JWT.typ = Nothing
+            , JWT.cty = Nothing
+            }
 
 -- These claims are documented here: https://developer.atlassian.com/cloud/jira/platform/oauth-2-jwt-bearer-token-authorization-grant-type/
 {-
@@ -126,7 +132,7 @@
         , JWT.exp = JWT.numericDate expiryTime
         , JWT.nbf = Nothing
         , JWT.jti = Nothing
-        , JWT.unregisteredClaims = M.fromList [("tnt", String . T.pack $ tenantBaseUrlString)]
+        , JWT.unregisteredClaims = JWT.ClaimsMap $ M.fromList [("tnt", String . T.pack $ tenantBaseUrlString)]
         }
     where
         tenantBaseUrlString = show . AC.getURI . AC.baseUrl $ tenant
@@ -138,5 +144,5 @@
         expiryPeriod :: Minute
         expiryPeriod = 1
 
-authBaseUrl :: T.Text 
+authBaseUrl :: T.Text
 authBaseUrl = "https://auth.atlassian.io"
