diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,5 +1,23 @@
 # ms-graph-api
 
-Microsoft Graph API
+Haskell client bindings to the [Microsoft Graph API v1.0](https://learn.microsoft.com/en-us/graph/api/overview?view=graph-rest-1.0).
+    
+[![Hackage](https://img.shields.io/hackage/v/ms-graph-api?style=for-the-badge)](https://hackage.haskell.org/package/ms-graph-api)
 
-https://learn.microsoft.com/en-us/graph/api/overview?view=graph-rest-1.0
+![main](https://github.com/unfoldml/ms-graph-api/actions/workflows/haskell.yml/badge.svg?branch=main)
+
+
+## Description
+
+This library provides both the client interface and authorization infrastructure to integrate with Microsoft infrastructure, e.g. using ActiveDirectory as an OAuth2 identity provider.
+
+## Status
+
+This library is still in development, so expect missing funcionality.
+If there's anything you would like to see added, feel free to
+[open an issue](https://github.com/unfoldml/ms-graph-api/issues/new).
+Some breaking changes might also be introduced as the library matures.
+
+## Copyright
+
+(c) 2023-, Marco Zocca, UnfoldML AB
diff --git a/ms-graph-api.cabal b/ms-graph-api.cabal
--- a/ms-graph-api.cabal
+++ b/ms-graph-api.cabal
@@ -1,5 +1,5 @@
 name:                ms-graph-api
-version:             0.2.0.0
+version:             0.3.0.0
 synopsis:            Microsoft Graph API
 description:         Bindings to the Microsoft Graph API
 homepage:            https://github.com/unfoldml/ms-graph-api
@@ -32,19 +32,16 @@
                      , aeson
                      , bytestring
                      , containers
-                     , hoauth2
+                     , hoauth2 == 2.6.0
                      , http-client
-                     , http-conduit
                      , http-types
                      , jwt
                      , modern-uri
                      , req
-                     , retry
                      , scientific
                      , scotty
-                     , stm
                      , text
-                     , time
+                     , time >= 1.8
                      , transformers >= 0.5
                      , unliftio
                      , uri-bytestring
diff --git a/src/Network/OAuth2/JWT.hs b/src/Network/OAuth2/JWT.hs
--- a/src/Network/OAuth2/JWT.hs
+++ b/src/Network/OAuth2/JWT.hs
@@ -18,8 +18,6 @@
 import qualified Data.Aeson as A (FromJSON(..), ToJSON(..), ToJSONKey(..), FromJSON(..), FromJSONKey(..), Value(..))
 -- containers
 import qualified Data.Map.Strict as M (Map, lookup)
--- -- hoauth2
--- import Network.OAuth.OAuth2 (OAuth2Token(..), IdToken(..))
 -- jwt
 import qualified Web.JWT as J (decode, claims, JWTClaimsSet(..), StringOrURI, NumericDate, ClaimsMap(..))
 -- scientific
diff --git a/src/Network/OAuth2/Provider/AzureAD.hs b/src/Network/OAuth2/Provider/AzureAD.hs
--- a/src/Network/OAuth2/Provider/AzureAD.hs
+++ b/src/Network/OAuth2/Provider/AzureAD.hs
@@ -20,7 +20,7 @@
 import qualified Data.Map.Strict as Map
 import qualified Data.Set as Set
 -- hoauth2
-import Network.OAuth.OAuth2 -- (authGetJSON, ClientSecretBasic)
+import Network.OAuth.OAuth2 (ClientAuthenticationMethod(..), authGetJSON)
 import Network.OAuth2.Experiment (IdpApplication(..), Idp(..), IdpUserInfo, GrantTypeFlow(..), ClientId(..), ClientSecret, Scope, AuthorizeState)
 -- text
 import qualified Data.Text as T (Text)
diff --git a/src/Network/OAuth2/Session.hs b/src/Network/OAuth2/Session.hs
--- a/src/Network/OAuth2/Session.hs
+++ b/src/Network/OAuth2/Session.hs
@@ -37,15 +37,11 @@
 -- -- heaps
 -- import qualified Data.Heap as H (Heap, empty, null, size, insert, viewMin, deleteMin, Entry(..), )
 -- hoauth2
-import Network.OAuth.OAuth2 (OAuth2Token(..))
-import Network.OAuth2.Experiment (IdpUserInfo, conduitUserInfoRequest, mkAuthorizeRequest, conduitTokenRequest, conduitRefreshTokenRequest)
-import Network.OAuth2.Experiment.Types (HasRefreshTokenRequest(..), WithExchangeToken(..), IdpApplication(..), GrantTypeFlow(..))
-import Network.OAuth.OAuth2.Internal (AccessToken(..), ExchangeToken(..), RefreshToken(..), OAuth2Error, IdToken(..))
+import Network.OAuth.OAuth2 (OAuth2Token(..), AccessToken(..), ExchangeToken(..), RefreshToken(..), OAuth2Error, IdToken(..))
+import Network.OAuth2.Experiment (IdpUserInfo, conduitUserInfoRequest, mkAuthorizeRequest, conduitTokenRequest, conduitRefreshTokenRequest, HasRefreshTokenRequest(..), WithExchangeToken, IdpApplication(..), GrantTypeFlow(..))
 import Network.OAuth.OAuth2.TokenRequest (Errors)
 -- http-client
 import Network.HTTP.Client (Manager)
--- http-conduit
-import Network.HTTP.Conduit (newManager, tlsManagerSettings)
 -- http-types
 import Network.HTTP.Types (status302, status400, status401)
 -- scotty
@@ -79,7 +75,7 @@
 --
 -- https://learn.microsoft.com/en-us/azure/app-service/configure-authentication-user-identities#access-user-claims-in-app-code
 
--- | The JWT identity token extracted from the headers injected by App Service can be decoded for its claims e.g. @sub@ (which is unique for each user for a given app)
+-- | The JWT identity token from the @X-MS-TOKEN-AAD-ID-TOKEN@ header injected by App Service can be decoded for its claims e.g. @sub@ (which is unique for each user for a given app)
 --
 -- https://bogdan.bynapse.com/azure/the-app-service-token-store-was-added-to-app-service-authentication-authorization-and-it-is-a-repository-of-oauth-tokens-associated-with-your-app-users-when-a-user-logs-into-your-app-via-an-iden/
 --
@@ -210,7 +206,8 @@
 refreshLoop ts idpApp mgr uid oaToken = forkFinally (act oaToken) cleanup
   where
     cleanup = \case
-      Left _ -> pure () -- FIXME what to do in case of auth errors?
+      Left _ -> do
+        expireUser ts uid -- auth error(s), remove user from memory
       Right _ -> pure ()
     act oat = do
       ein <- updateToken ts uid oat -- replace new token in memory
