diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,8 @@
+0.9.7.1
+=======
+
+* Fixed cabal source distribution
+
 0.9.7
 =====
 
diff --git a/sproxy.cabal b/sproxy.cabal
--- a/sproxy.cabal
+++ b/sproxy.cabal
@@ -1,5 +1,5 @@
 name: sproxy
-version: 0.9.7
+version: 0.9.7.1
 synopsis: HTTP proxy for authenticating users via OAuth2
 license: MIT
 license-file: LICENSE
@@ -24,6 +24,7 @@
     Authenticate.Google
     Authenticate.LinkedIn
     Authenticate.Token
+    Authenticate.Types
     Authorize
     ConfigFile
     Cookies
diff --git a/src/Authenticate/Types.hs b/src/Authenticate/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/Authenticate/Types.hs
@@ -0,0 +1,39 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Authenticate.Types (
+  AccessToken(..)
+, AuthConfig(..)
+, OAuthClient(..)
+) where
+
+import Control.Applicative (empty)
+import Data.Aeson (FromJSON, parseJSON, Value(Object), (.:), (.:?))
+import Data.ByteString (ByteString)
+import System.Posix.Types (EpochTime)
+
+data OAuthClient = OAuthClient {
+  oauthClientId :: ByteString
+, oauthClientSecret :: ByteString
+} deriving (Eq, Show)
+
+data AuthConfig = AuthConfig {
+  authConfigCookieDomain   :: String
+, authConfigCookieName     :: String
+, authConfigGoogleClient   :: Maybe OAuthClient
+, authConfigLinkedInClient :: Maybe OAuthClient
+, authConfigAuthTokenKey   :: String
+, authConfigShelfLife      :: EpochTime
+} deriving (Eq, Show)
+
+-- | RFC6749. We ignore optional token_type ("Bearer" from Google, omitted by LinkedIn)
+--   and expires_in because we don't use them, *and* expires_in creates troubles:
+--   it's an integer from Google and string from LinkedIn (sic!)
+data AccessToken = AccessToken {
+  accessToken :: String
+} deriving (Eq, Show)
+
+instance FromJSON AccessToken where
+  parseJSON (Object v) = AccessToken
+    <$> v .:  "access_token"
+  parseJSON _ = empty
+
