diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -39,7 +39,11 @@
 To get started with the library it is best to read the documentation of the
 `Crypto.WebAuthn` module. An example of how to use this library to implement a
 relying party can be found in the `server` directory, particularly the
-`server/src/Main.hs` module.
+`server/src/Main.hs` module. Additionally, we highly recommend reading the
+[relying party section](https://www.w3.org/TR/webauthn-2/#sctn-security-considerations-rp)
+of the
+[WebAuthn security considerations chapter](https://www.w3.org/TR/webauthn-2/#sctn-security-considerations)
+before implementing a relying party.
 
 ## Developing the Library
 The [Haskell Language Server (hls)][hls] and [Ormolu][ormolu] are highly
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,10 @@
+### 0.3.0.0
+
+* [#125](https://github.com/tweag/webauthn/pull/125) Some small metadata type
+  simplifications involving `msUpv` and `SomeMetadataEntry`
+* [#126](https://github.com/tweag/webauthn/pull/126) Decrease lower bounds of
+  many dependencies including `base`, adding compatibility with GHC 8.8
+
 ### 0.2.0.0
 
 * [#115](https://github.com/tweag/webauthn/pull/115) Increase the upper bound
diff --git a/src/Crypto/WebAuthn.hs b/src/Crypto/WebAuthn.hs
--- a/src/Crypto/WebAuthn.hs
+++ b/src/Crypto/WebAuthn.hs
@@ -79,6 +79,14 @@
 -- [a potential implementation](https://github.com/tweag/webauthn/blob/master/server/www/unauthenticated.js).
 -- See also these [Sample API Usage Scenarios](https://www.w3.org/TR/webauthn-2/#sctn-sample-scenarios).
 --
+-- == WebAuthn Security considerations
+--
+-- [Chapter 13](https://www.w3.org/TR/webauthn-2/#sctn-security-considerations)
+-- details the security considerations of WebAuthn. It is highly recommend to
+-- read at least the
+-- [relying party section](https://www.w3.org/TR/webauthn-2/#sctn-security-considerations-rp)
+-- of these considerations before implementing a relying party.
+--
 -- == Library
 --
 -- The two ceremonies described above are very similar in many ways. Because of
diff --git a/src/Crypto/WebAuthn/Metadata/Service/Decode.hs b/src/Crypto/WebAuthn/Metadata/Service/Decode.hs
--- a/src/Crypto/WebAuthn/Metadata/Service/Decode.hs
+++ b/src/Crypto/WebAuthn/Metadata/Service/Decode.hs
@@ -55,19 +55,18 @@
       Left Nothing
     (Nothing, Just aaguid, Nothing) -> do
       -- This is a FIDO 2 entry
-      identifier <- first Just $ decodeAAGUID aaguid
+      meIdentifier <- first Just $ decodeAAGUID aaguid
       meMetadataStatement <- traverse decodeMetadataStatement metadataStatement
       meStatusReports <- first Just $ traverse decodeStatusReport statusReports
       meTimeOfLastStatusChange <- first Just $ decodeDate timeOfLastStatusChange
-      Right $ pure $ ServiceTypes.SomeMetadataEntry identifier ServiceTypes.MetadataEntry {..}
+      Right $ pure $ ServiceTypes.SomeMetadataEntry ServiceTypes.MetadataEntry {..}
     (Nothing, Nothing, Just attestationCertificateKeyIdentifiers) -> do
       -- This is a FIDO U2F entry
       identifiers <- first Just $ traverse decodeSubjectKeyIdentifier attestationCertificateKeyIdentifiers
       meMetadataStatement <- traverse decodeMetadataStatement metadataStatement
       meStatusReports <- first Just $ traverse decodeStatusReport statusReports
       meTimeOfLastStatusChange <- first Just $ decodeDate timeOfLastStatusChange
-      let entry = ServiceTypes.MetadataEntry {..}
-      Right $ fmap (`ServiceTypes.SomeMetadataEntry` entry) identifiers
+      Right $ fmap (\meIdentifier -> ServiceTypes.SomeMetadataEntry ServiceTypes.MetadataEntry {..}) identifiers
     (Nothing, Nothing, Nothing) ->
       Left $ Just "None of aaid, aaguid or attestationCertificateKeyIdentifiers are set for this entry"
     _ ->
diff --git a/src/Crypto/WebAuthn/Metadata/Service/Processing.hs b/src/Crypto/WebAuthn/Metadata/Service/Processing.hs
--- a/src/Crypto/WebAuthn/Metadata/Service/Processing.hs
+++ b/src/Crypto/WebAuthn/Metadata/Service/Processing.hs
@@ -4,7 +4,6 @@
 {-# LANGUAGE GADTs #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE RecordWildCards #-}
-{-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TemplateHaskell #-}
 
 -- | Stability: experimental
@@ -49,12 +48,7 @@
 import qualified Crypto.WebAuthn.Model as M
 import Crypto.WebAuthn.Model.Identifier
   ( AAGUID,
-    AuthenticatorIdentifier
-      ( AuthenticatorIdentifierFido2,
-        AuthenticatorIdentifierFidoU2F,
-        idAaguid,
-        idSubjectKeyIdentifier
-      ),
+    AuthenticatorIdentifier (AuthenticatorIdentifierFido2, AuthenticatorIdentifierFidoU2F),
     SubjectKeyIdentifier,
   )
 import Data.Aeson (Value)
@@ -67,7 +61,6 @@
 import qualified Data.HashMap.Strict as HashMap
 import Data.Hourglass (DateTime)
 import qualified Data.List.NonEmpty as NE
-import Data.Singletons (singByProxy)
 import Data.Text (Text)
 import qualified Data.Text as Text
 import qualified Data.X509 as X509
@@ -222,9 +215,9 @@
     (fido2Pairs, fidoU2FPairs) = partitionEithers $ map fromSomeMetadataEntry entries
 
     fromSomeMetadataEntry :: Service.SomeMetadataEntry -> Either (AAGUID, Service.MetadataEntry 'M.Fido2) (SubjectKeyIdentifier, Service.MetadataEntry 'M.FidoU2F)
-    fromSomeMetadataEntry (Service.SomeMetadataEntry ident entry) = case singByProxy ident of
-      M.SFido2 -> Left (idAaguid ident, entry)
-      M.SFidoU2F -> Right (idSubjectKeyIdentifier ident, entry)
+    fromSomeMetadataEntry (Service.SomeMetadataEntry entry@Service.MetadataEntry {..}) = case meIdentifier of
+      AuthenticatorIdentifierFido2 aaguid -> Left (aaguid, entry)
+      AuthenticatorIdentifierFidoU2F subjectKeyIdentifier -> Right (subjectKeyIdentifier, entry)
 
 -- | Query a 'Service.MetadataEntry' for an 'M.AuthenticatorIdentifier'
 queryMetadata ::
diff --git a/src/Crypto/WebAuthn/Metadata/Service/Types.hs b/src/Crypto/WebAuthn/Metadata/Service/Types.hs
--- a/src/Crypto/WebAuthn/Metadata/Service/Types.hs
+++ b/src/Crypto/WebAuthn/Metadata/Service/Types.hs
@@ -73,8 +73,10 @@
 -- Same as 'StatementIDL.MetadataBLOBPayloadEntry', but fully decoded. This type
 -- is parametrized over the 'StatementIDL.ProtocolFamily' this metadata entry is for
 data MetadataEntry (p :: M.ProtocolKind) = MetadataEntry
-  { -- [(spec)](https://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html#dom-metadatablobpayloadentry-metadatastatement)
-    meMetadataStatement :: Maybe (MetadataStatement p),
+  { -- | [(spec)](https://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html#dom-metadatablobpayloadentry-aaguid) or [(spec)](https://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html#dom-metadatablobpayloadentry-attestationcertificatekeyidentifiers)
+    meIdentifier :: AuthenticatorIdentifier p,
+    -- | [(spec)](https://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html#dom-metadatablobpayloadentry-metadatastatement)
+    meMetadataStatement :: Maybe MetadataStatement,
     -- TODO: Implement this, currently not used in the blob however
     -- meBiometricStatusReports :: Maybe (NonEmpty BiometricStatusReport),
 
@@ -88,7 +90,7 @@
   deriving (Eq, Show, Generic, ToJSON)
 
 -- | Same as 'MetadataEntry', but with its type parameter erased
-data SomeMetadataEntry = forall p. SingI p => SomeMetadataEntry (AuthenticatorIdentifier p) (MetadataEntry p)
+data SomeMetadataEntry = forall p. SingI p => SomeMetadataEntry (MetadataEntry p)
 
 -- | [(spec)](https://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html#statusreport-dictionary)
 -- Same as 'StatementIDL.StatusReport', but fully decoded.
diff --git a/src/Crypto/WebAuthn/Metadata/Statement/Decode.hs b/src/Crypto/WebAuthn/Metadata/Statement/Decode.hs
--- a/src/Crypto/WebAuthn/Metadata/Statement/Decode.hs
+++ b/src/Crypto/WebAuthn/Metadata/Statement/Decode.hs
@@ -1,7 +1,5 @@
 {-# LANGUAGE DataKinds #-}
-{-# LANGUAGE GADTs #-}
 {-# LANGUAGE RecordWildCards #-}
-{-# LANGUAGE ScopedTypeVariables #-}
 
 -- | Stability: experimental
 -- This module contains functions to further decode
@@ -21,7 +19,6 @@
 import Crypto.WebAuthn.Metadata.Statement.Types (WebauthnAttestationType (WebauthnAttestationAttCA, WebauthnAttestationBasic))
 import qualified Crypto.WebAuthn.Metadata.Statement.Types as StatementTypes
 import qualified Crypto.WebAuthn.Metadata.Statement.WebIDL as StatementIDL
-import qualified Crypto.WebAuthn.Metadata.UAF as UAF
 import qualified Crypto.WebAuthn.Model as M
 import Crypto.WebAuthn.Model.Identifier (AAGUID (AAGUID), AuthenticatorIdentifier (AuthenticatorIdentifierFido2, AuthenticatorIdentifierFidoU2F), SubjectKeyIdentifier (SubjectKeyIdentifier))
 import qualified Crypto.WebAuthn.WebIDL as IDL
@@ -32,7 +29,6 @@
 import Data.List.NonEmpty (NonEmpty)
 import qualified Data.List.NonEmpty as NE
 import Data.Maybe (mapMaybe)
-import Data.Singletons (SingI, sing)
 import Data.Text (Text)
 import qualified Data.Text as Text
 import Data.Text.Encoding (encodeUtf8)
@@ -68,25 +64,21 @@
 -- | Fully decodes a [MetadataStatement](https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.0-ps-20210518.html#metadata-keys).
 -- The @p@ type parameter is the 'StatementIDL.ProtocolFamily' that this metadata statement is for.
 decodeMetadataStatement ::
-  forall p.
-  SingI p =>
   -- | The raw metadata statement, directly parsed from JSON
   StatementIDL.MetadataStatement ->
   -- | Either an early exit with 'Left', where @Left Nothing@ signals that
   -- this entry can be skipped because it's not relevant for Webauthn, and
   -- @Left . Just@ signals that an error happened during decoding
   -- Otherwise a successful result with 'Right'
-  Either (Maybe Text) (StatementTypes.MetadataStatement p)
+  Either (Maybe Text) StatementTypes.MetadataStatement
 decodeMetadataStatement StatementIDL.MetadataStatement {..} = do
   let msLegalHeader = legalHeader
       msDescription = description
       msAlternativeDescriptions = alternativeDescriptions
       msAuthenticatorVersion = authenticatorVersion
   unless (schema == 3) $ Left $ Just $ "Schema version is not 3 but " <> Text.pack (show schema)
-  msUpv <- case sing @p of
-    M.SFidoU2F -> first Just $ traverse decodeUpvFidoU2F upv
-    M.SFido2 -> first Just $ traverse decodeUpvFido2 upv
-  let msAuthenticationAlgorithms = authenticationAlgorithms
+  let msUpv = upv
+      msAuthenticationAlgorithms = authenticationAlgorithms
       msPublicKeyAlgAndEncodings = publicKeyAlgAndEncodings
   msAttestationTypes <- decodeAttestationTypes attestationTypes
   let msUserVerificationDetails = userVerificationDetails
@@ -109,17 +101,6 @@
       msAuthenticatorGetInfo = authenticatorGetInfo
   pure $ StatementTypes.MetadataStatement {..}
   where
-    decodeUpvFidoU2F :: UAF.Version -> Either Text (StatementTypes.ProtocolVersion 'M.FidoU2F)
-    decodeUpvFidoU2F UAF.Version {UAF.major = 1, UAF.minor = 0} = Right StatementTypes.U2F1_0
-    decodeUpvFidoU2F UAF.Version {UAF.major = 1, UAF.minor = 1} = Right StatementTypes.U2F1_1
-    decodeUpvFidoU2F UAF.Version {UAF.major = 1, UAF.minor = 2} = Right StatementTypes.U2F1_2
-    decodeUpvFidoU2F version = Left $ "Unknown FIDO U2F UPV version: " <> Text.pack (show version)
-
-    decodeUpvFido2 :: UAF.Version -> Either Text (StatementTypes.ProtocolVersion 'M.Fido2)
-    decodeUpvFido2 UAF.Version {UAF.major = 1, UAF.minor = 0} = Right StatementTypes.CTAP2_0
-    decodeUpvFido2 UAF.Version {UAF.major = 1, UAF.minor = 1} = Right StatementTypes.CTAP2_1
-    decodeUpvFido2 version = Left $ "Unknown FIDO2 UPV version: " <> Text.pack (show version)
-
     -- Turns a non-empty list of 'Registry.AuthenticatorAttestationType' into a non-empty list of 'WebauthnAttestationType'.
     -- If the authenticator doesn't support any webauthn attestation types,
     -- `Left Nothing` is returned, indicating that this authenticator should be ignored
diff --git a/src/Crypto/WebAuthn/Metadata/Statement/Types.hs b/src/Crypto/WebAuthn/Metadata/Statement/Types.hs
--- a/src/Crypto/WebAuthn/Metadata/Statement/Types.hs
+++ b/src/Crypto/WebAuthn/Metadata/Statement/Types.hs
@@ -1,23 +1,17 @@
-{-# LANGUAGE DataKinds #-}
-{-# LANGUAGE GADTs #-}
-{-# LANGUAGE KindSignatures #-}
-{-# LANGUAGE StandaloneDeriving #-}
-
 -- | Stability: experimental
 -- This module contains additional Haskell-specific type definitions for the
 -- [FIDO Metadata Statement](https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.0-ps-20210518.html)
 -- specification
 module Crypto.WebAuthn.Metadata.Statement.Types
   ( MetadataStatement (..),
-    ProtocolVersion (..),
     WebauthnAttestationType (..),
   )
 where
 
 import qualified Crypto.WebAuthn.Metadata.FidoRegistry as Registry
 import qualified Crypto.WebAuthn.Metadata.Statement.WebIDL as StatementIDL
-import qualified Crypto.WebAuthn.Model as M
-import Data.Aeson (ToJSON, toJSON)
+import qualified Crypto.WebAuthn.Metadata.UAF as UAF
+import Data.Aeson (ToJSON)
 import qualified Data.ByteString as BS
 import Data.List.NonEmpty (NonEmpty)
 import Data.Text (Text)
@@ -27,7 +21,7 @@
 import GHC.Word (Word16)
 
 -- | [(spec)](https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.0-ps-20210518.html#metadata-keys)
-data MetadataStatement (p :: M.ProtocolKind) = MetadataStatement
+data MetadataStatement = MetadataStatement
   { -- | [(spec)](https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.0-ps-20210518.html#dom-metadatastatement-legalheader)
     msLegalHeader :: Text,
     -- msAaid, msAaguid, attestationCertificateKeyIdentifiers: These fields are the key of the hashmaps in MetadataServiceRegistry
@@ -42,7 +36,7 @@
     -- msSchema, this is always schema version 3
 
     -- | [(spec)](https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.0-ps-20210518.html#dom-metadatastatement-upv)
-    msUpv :: NonEmpty (ProtocolVersion p),
+    msUpv :: NonEmpty UAF.Version,
     -- | [(spec)](https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.0-ps-20210518.html#dom-metadatastatement-authenticationalgorithms)
     msAuthenticationAlgorithms :: NonEmpty Registry.AuthenticationAlgorithm,
     -- | [(spec)](https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.0-ps-20210518.html#dom-metadatastatement-publickeyalgandencodings)
@@ -81,30 +75,6 @@
     msAuthenticatorGetInfo :: Maybe StatementIDL.AuthenticatorGetInfo
   }
   deriving (Eq, Show, Generic, ToJSON)
-
--- | FIDO protocol versions, parametrized by the protocol family
-data ProtocolVersion (p :: M.ProtocolKind) where
-  -- | FIDO U2F 1.0
-  U2F1_0 :: ProtocolVersion 'M.FidoU2F
-  -- | FIDO U2F 1.1
-  U2F1_1 :: ProtocolVersion 'M.FidoU2F
-  -- | FIDO U2F 1.2
-  U2F1_2 :: ProtocolVersion 'M.FidoU2F
-  -- | FIDO 2, CTAP 2.0
-  CTAP2_0 :: ProtocolVersion 'M.Fido2
-  -- | FIDO 2, CTAP 2.1
-  CTAP2_1 :: ProtocolVersion 'M.Fido2
-
-deriving instance Eq (ProtocolVersion p)
-
-deriving instance Show (ProtocolVersion p)
-
-instance ToJSON (ProtocolVersion p) where
-  toJSON U2F1_0 = "U2F 1.0"
-  toJSON U2F1_1 = "U2F 1.1"
-  toJSON U2F1_2 = "U2F 1.2"
-  toJSON CTAP2_0 = "CTAP 2.0"
-  toJSON CTAP2_1 = "CTAP 2.1"
 
 -- | Values of 'Registry.AuthenticatorAttestationType' but limited to the ones possible with Webauthn, see https://www.w3.org/TR/webauthn-2/#sctn-attestation-types
 data WebauthnAttestationType
diff --git a/src/Crypto/WebAuthn/Metadata/Statement/WebIDL.hs b/src/Crypto/WebAuthn/Metadata/Statement/WebIDL.hs
--- a/src/Crypto/WebAuthn/Metadata/Statement/WebIDL.hs
+++ b/src/Crypto/WebAuthn/Metadata/Statement/WebIDL.hs
@@ -1,4 +1,3 @@
-{-# LANGUAGE DataKinds #-}
 {-# LANGUAGE DuplicateRecordFields #-}
 
 -- | Stability: experimental
diff --git a/src/Crypto/WebAuthn/Operation/Registration.hs b/src/Crypto/WebAuthn/Operation/Registration.hs
--- a/src/Crypto/WebAuthn/Operation/Registration.hs
+++ b/src/Crypto/WebAuthn/Operation/Registration.hs
@@ -513,7 +513,7 @@
 -- | Metadata statements can convey multiple attestation types.
 -- In such a case we choose to result in the Uncertain type.
 -- Otherwise, we results in the only one available.
-fixupVerifiableAttestationType :: M.VerifiableAttestationType -> Meta.MetadataStatement p -> M.VerifiableAttestationType
+fixupVerifiableAttestationType :: M.VerifiableAttestationType -> Meta.MetadataStatement -> M.VerifiableAttestationType
 fixupVerifiableAttestationType M.VerifiableAttestationTypeUncertain statement =
   case Meta.msAttestationTypes statement of
     -- If there are multiple types we can't know which one it is
diff --git a/webauthn.cabal b/webauthn.cabal
--- a/webauthn.cabal
+++ b/webauthn.cabal
@@ -1,6 +1,6 @@
 cabal-version: 2.4
 name: webauthn
-version: 0.2.0.0
+version: 0.3.0.0
 license: Apache-2.0
 license-file: LICENSE
 copyright:
@@ -73,33 +73,33 @@
   import: sanity
   hs-source-dirs: src
   build-depends:
-    base                  >= 4.14.3 && < 4.15,
-    aeson                 >= 1.4.7.1 && < 2.1,
+    base                  >= 4.13.0 && < 4.15,
+    aeson                 >= 1.4.7 && < 2.1,
     asn1-encoding         >= 0.9.6 && < 0.10,
     asn1-parse            >= 0.9.5 && < 0.10,
     asn1-types            >= 0.3.4 && < 0.4,
-    base16-bytestring     >= 1.0.2 && < 1.1,
+    base16-bytestring     >= 1.0.0 && < 1.1,
     base64-bytestring     >= 1.2.1 && < 1.3,
-    binary                >= 0.8.8 && < 0.9,
-    bytestring            >= 0.10.12 && < 0.11,
-    cborg                 >= 0.2.6 && < 0.3,
-    containers            >= 0.6.5 && < 0.7,
-    cryptonite            >= 0.29 && < 0.30,
-    file-embed            >= 0.0.15 && < 0.1,
+    binary                >= 0.8.7 && < 0.9,
+    bytestring            >= 0.10.10 && < 0.11,
+    cborg                 >= 0.2.4 && < 0.3,
+    containers            >= 0.6.2 && < 0.7,
+    cryptonite            >= 0.27 && < 0.30,
+    file-embed            >= 0.0.11 && < 0.1,
     hashable              >= 1.3.0 && < 1.5,
     hourglass             >= 0.2.12 && < 0.3,
     jose                  >= 0.8.5 && < 0.10,
-    lens                  >= 4.19.2 && < 4.20,
+    lens                  >= 4.18.1 && < 4.20,
     memory                >= 0.15.0 && < 0.16,
     monad-time            >= 0.3.1 && < 0.4,
     mtl                   >= 2.2.2 && < 2.3,
-    serialise             >= 0.2.4 && < 0.3,
-    singletons            >= 2.7 && < 2.8,
+    serialise             >= 0.2.3 && < 0.3,
+    singletons            >= 2.6 && < 2.8,
     text                  >= 1.2.4 && < 1.3,
     time                  >= 1.9.3 && < 1.10,
-    unordered-containers  >= 0.2.11.0 && < 0.3,
-    uuid                  >= 1.3.15 && < 1.4,
-    validation            >= 1.1.2 && < 1.2,
+    unordered-containers  >= 0.2.11 && < 0.3,
+    uuid                  >= 1.3.13 && < 1.4,
+    validation            >= 1.1 && < 1.2,
     x509                  >= 1.7.5 && < 1.8,
     x509-store            >= 1.6.7 && < 1.7,
     x509-validation       >= 1.6.12 && < 1.7
