diff --git a/examples/deploy/Deploy/Deploy.hs b/examples/deploy/Deploy/Deploy.hs
--- a/examples/deploy/Deploy/Deploy.hs
+++ b/examples/deploy/Deploy/Deploy.hs
@@ -12,7 +12,6 @@
 import qualified Data.Text                    as T
 import qualified Data.Aeson                   as A
 import qualified Data.HashMap.Strict          as HM
-import           Control.Applicative
 
 
 deploy :: IC -> HostID -> IO LBS.ByteString
diff --git a/examples/deploy/Deploy/HostSectionKey.hs b/examples/deploy/Deploy/HostSectionKey.hs
--- a/examples/deploy/Deploy/HostSectionKey.hs
+++ b/examples/deploy/Deploy/HostSectionKey.hs
@@ -14,7 +14,6 @@
 import qualified Data.ByteString.Char8          as B
 import qualified Data.ByteString.Lazy.Char8     as LBS
 import qualified Text.RawString.QQ              as RS
-import           Control.Monad.RWS.Strict
 import           Text.Printf
 
 
diff --git a/keystore.cabal b/keystore.cabal
--- a/keystore.cabal
+++ b/keystore.cabal
@@ -1,5 +1,5 @@
 Name:                   keystore
-Version:                0.8.0.2
+Version:                0.8.1.0
 Synopsis:               Managing stores of secret things
 Homepage:               http://github.com/cdornan/keystore
 Author:                 Chris Dornan
@@ -164,18 +164,19 @@
         Data.KeyStore.Types.PasswordStoreModel
         Data.KeyStore.Types.PasswordStoreSchema
         Data.KeyStore.Types.Schema
+        Data.KeyStore.Types.UTC
         Data.KeyStore.Version
 
     Build-depends:
-        api-tools              >= 0.4               ,
+        api-tools              >= 0.5.2             ,
         asn1-types             >= 0.2.0             ,
         asn1-encoding          >= 0.8.0             ,
         ansi-wl-pprint         >= 0.6.7             ,
         crypto-pubkey          >= 0.2.1             ,
         crypto-random          >= 0.0.7             ,
-        aeson                  >= 0.6.2             ,
+        aeson                  >= 0.8               ,
         aeson-pretty           >= 0.7               ,
-        base                   >= 4                 ,
+        base                   >= 4.8               ,
         base64-bytestring      >= 1.0               ,
         byteable               >= 0.1               ,
         bytestring             >= 0.9               ,
@@ -186,13 +187,14 @@
         lens                   >= 3.9.2             ,
         mtl                    >= 2                 ,
         old-locale             >= 1.0.0.5           ,
-        optparse-applicative   >= 0.11.0   && <0.14 ,
+        optparse-applicative   >= 0.11.0            ,
         pbkdf                  >= 1.1.1.0           ,
+        regex                  >= 1.0.1.3           ,
         regex-compat-tdfa      >= 0.95.1            ,
         safe                   >= 0.3.3             ,
         setenv                 >= 0.1               ,
         text                   >= 0.11.3            ,
-        time                   >= 1.4               ,
+        time                   >= 1.5               ,
         unordered-containers   >= 0.2.3.0           ,
         vector                 >= 0.10.0.1
 
@@ -231,18 +233,18 @@
     Build-depends:
         api-tools              >= 0.4               ,
         ansi-wl-pprint         >= 0.6.7.1           ,
-        aeson                  >= 0.6.2             ,
-        base                   >  4 && < 5          ,
+        aeson                  >= 0.8               ,
+        base                   >= 4.8               ,
         bytestring             >= 0.9               ,
         directory              >= 1.0               ,
         filepath               >= 1.1               ,
         keystore                                    ,
         mtl                    >= 2                 ,
-        optparse-applicative   >= 0.9.0             ,
+        optparse-applicative   >= 0.11.0            ,
         process                >= 1.2.0.0           ,
         raw-strings-qq         >= 1.0.2             ,
         setenv                 >= 0.1               ,
-        text                   >= 0.11              ,
+        text                   >= 0.11.3            ,
         unordered-containers   >= 0.2.3.0
 
     GHC-Options:
diff --git a/src/Data/KeyStore/IO.hs b/src/Data/KeyStore/IO.hs
--- a/src/Data/KeyStore/IO.hs
+++ b/src/Data/KeyStore/IO.hs
@@ -83,7 +83,6 @@
 import qualified Data.Map                       as Map
 import           Data.Time
 import           Text.Printf
-import           Control.Applicative
 import qualified Control.Exception              as X
 import qualified Control.Lens                   as L
 import           Control.Monad
@@ -395,7 +394,7 @@
 putCtxState IC{..} ctx st =
  do maybe (return ()) (flip writeIORef (ctx,st)) ic_cache
     when (not $ maybe False id $ cp_readonly ic_ctx_params) $
-        LBS.writeFile (ctx_store ctx) $ keyStoreBytes $ st_keystore st
+      LBS.writeFile (ctx_store ctx) $ keyStoreBytes $ st_keystore st
 
 report :: String -> IO ()
 report = hPutStrLn stderr
diff --git a/src/Data/KeyStore/IO/IC.hs b/src/Data/KeyStore/IO/IC.hs
--- a/src/Data/KeyStore/IO/IC.hs
+++ b/src/Data/KeyStore/IO/IC.hs
@@ -31,7 +31,6 @@
 import           Data.Time
 import           Data.IORef
 import qualified Control.Exception              as X
-import           Control.Applicative
 import           System.Environment
 import           System.Directory
 import           System.FilePath
diff --git a/src/Data/KeyStore/KS.hs b/src/Data/KeyStore/KS.hs
--- a/src/Data/KeyStore/KS.hs
+++ b/src/Data/KeyStore/KS.hs
@@ -48,7 +48,6 @@
 import           Data.List
 import           Data.Time
 import           Text.Printf
-import           Control.Applicative
 import qualified Control.Lens                   as L
 import           Control.Monad
 
diff --git a/src/Data/KeyStore/KS/CPRNG.hs b/src/Data/KeyStore/KS/CPRNG.hs
--- a/src/Data/KeyStore/KS/CPRNG.hs
+++ b/src/Data/KeyStore/KS/CPRNG.hs
@@ -9,7 +9,6 @@
     ) where
 
 import           Crypto.Random
-import           Control.Applicative
 import qualified Data.ByteString                as B
 
 
diff --git a/src/Data/KeyStore/KS/Configuration.hs b/src/Data/KeyStore/KS/Configuration.hs
--- a/src/Data/KeyStore/KS/Configuration.hs
+++ b/src/Data/KeyStore/KS/Configuration.hs
@@ -3,7 +3,6 @@
 module Data.KeyStore.KS.Configuration where
 
 import           Data.KeyStore.Types
-import           Data.Monoid
 import qualified Data.Map               as Map
 import           Data.Maybe
 import           Text.Regex
diff --git a/src/Data/KeyStore/KS/Crypto.hs b/src/Data/KeyStore/KS/Crypto.hs
--- a/src/Data/KeyStore/KS/Crypto.hs
+++ b/src/Data/KeyStore/KS/Crypto.hs
@@ -55,7 +55,6 @@
 import qualified Data.ASN1.Types                as A
 import qualified Data.ByteString.Lazy.Char8     as LBS
 import qualified Data.ByteString.Char8          as B
-import           Control.Applicative
 import           Crypto.PubKey.RSA
 import qualified Crypto.PubKey.RSA.OAEP         as OAEP
 import qualified Crypto.PubKey.RSA.PSS          as PSS
diff --git a/src/Data/KeyStore/KS/KS.hs b/src/Data/KeyStore/KS/KS.hs
--- a/src/Data/KeyStore/KS/KS.hs
+++ b/src/Data/KeyStore/KS/KS.hs
@@ -44,7 +44,6 @@
 import qualified Data.ByteString                as B
 import           Data.Typeable
 import           Data.Time
-import           Control.Applicative
 import           Control.Monad.RWS.Strict
 import qualified Control.Monad.Error            as E
 import           Control.Exception
diff --git a/src/Data/KeyStore/KS/Opt.hs b/src/Data/KeyStore/KS/Opt.hs
--- a/src/Data/KeyStore/KS/Opt.hs
+++ b/src/Data/KeyStore/KS/Opt.hs
@@ -41,7 +41,6 @@
 import           Data.Maybe
 import           Data.Char
 import           Text.Printf
-import           Control.Applicative
 
 
 data Opt a
diff --git a/src/Data/KeyStore/KS/Packet.hs b/src/Data/KeyStore/KS/Packet.hs
--- a/src/Data/KeyStore/KS/Packet.hs
+++ b/src/Data/KeyStore/KS/Packet.hs
@@ -21,7 +21,6 @@
 import           Data.Bits
 import           Data.Char
 import           Text.Printf
-import           Control.Applicative
 import           Control.Monad.RWS.Strict
 import qualified Control.Monad.Error            as E
 
diff --git a/src/Data/KeyStore/PasswordManager.hs b/src/Data/KeyStore/PasswordManager.hs
--- a/src/Data/KeyStore/PasswordManager.hs
+++ b/src/Data/KeyStore/PasswordManager.hs
@@ -346,7 +346,7 @@
             { _ssn_name      = _sd_name
             , _ssn_password  = pwt
             , _ssn_isOneShot = ios
-            , _ssn_setup     = now
+            , _ssn_setup     = UTC now
             }
 
         ios         = _sd_isOneShot
@@ -579,7 +579,7 @@
         pn_s = T.unpack $ _PasswordName _pw_name
         sn_s = T.unpack $ _SessionName  _ssn_name
         p_c  = if _ssn_isOneShot then prime_char False else ' '
-        su_s = pretty_setup tz _ssn_setup
+        su_s = pretty_setup tz $ _UTC _ssn_setup
         a_s  = if active_session trp then "[ACTIVE]" else "" :: String
 
     sgl = length [ () | p<-[minBound..maxBound], isJust $ isSession $ cast_pmc pmc p ] == 1
diff --git a/src/Data/KeyStore/Types.hs b/src/Data/KeyStore/Types.hs
--- a/src/Data/KeyStore/Types.hs
+++ b/src/Data/KeyStore/Types.hs
@@ -30,31 +30,32 @@
     ( module Data.KeyStore.Types
     , module Data.KeyStore.Types.NameAndSafeguard
     , module Data.KeyStore.Types.E
+    , module Data.KeyStore.Types.UTC
     , PublicKey(..)
     , PrivateKey(..)
     ) where
 
+import qualified Control.Lens                   as L
+import qualified Crypto.PBKDF.ByteString        as P
+import           Crypto.PubKey.RSA (PublicKey(..), PrivateKey(..))
 import           Data.KeyStore.Types.Schema
 import           Data.KeyStore.Types.NameAndSafeguard
 import           Data.KeyStore.Types.E
+import           Data.KeyStore.Types.UTC
 import           Data.Aeson
-import           Data.Aeson.Encoding
-import qualified Data.Map                       as Map
-import           Data.Monoid
-import qualified Data.Text                      as T
-import           Data.List
-import           Data.Ord
-import           Data.String
 import           Data.API.Tools
-import           Data.API.Types
 import           Data.API.JSON
+import           Data.API.Types
 import qualified Data.ByteString                as B
 import qualified Data.HashMap.Strict            as HM
+import           Data.List
+import qualified Data.Map                       as Map
+import           Data.Ord
 import qualified Data.Text                      as T
+import           Data.Time
+import           Data.String
 import qualified Data.Vector                    as V
 import           Text.Regex
-import qualified Crypto.PBKDF.ByteString        as P
-import           Crypto.PubKey.RSA (PublicKey(..), PrivateKey(..))
 
 
 $(generate                         keystoreSchema)
@@ -103,15 +104,6 @@
 prj_pattern = REP__Pattern . T.pack . _pat_string
 
 
-type TriggerMap = Map.Map TriggerID Trigger
-
-inj_trigger_map :: REP__TriggerMap -> ParserWithErrs TriggerMap
-inj_trigger_map = map_from_list "TriggerMap" _tmp_map _trg_id _TriggerID
-
-prj_trigger_map :: TriggerMap -> REP__TriggerMap
-prj_trigger_map = REP__TriggerMap . Map.elems
-
-
 newtype Settings = Settings { _Settings :: Object }
     deriving (Eq,Show)
 
@@ -146,43 +138,6 @@
 marker = String "*** Collision * in * Settings ***"
 
 
-type KeyMap = Map.Map Name Key
-
-inj_keymap :: REP__KeyMap -> ParserWithErrs KeyMap
-inj_keymap (REP__KeyMap as) =
-        return $ Map.fromList [ (_nka_name,_nka_key) | NameKeyAssoc{..}<-as ]
-
-prj_keymap :: KeyMap -> REP__KeyMap
-prj_keymap mp = REP__KeyMap [ NameKeyAssoc nme key | (nme,key)<-Map.toList mp ]
-
-emptyKeyStore :: Configuration -> KeyStore
-emptyKeyStore cfg =
-    KeyStore
-        { _ks_config = cfg
-        , _ks_keymap = emptyKeyMap
-        }
-
-emptyKeyMap :: KeyMap
-emptyKeyMap = Map.empty
-
-
-type EncrypedCopyMap = Map.Map Safeguard EncrypedCopy
-
-inj_encrypted_copy_map :: REP__EncrypedCopyMap -> ParserWithErrs EncrypedCopyMap
-inj_encrypted_copy_map (REP__EncrypedCopyMap ecs) =
-        return $ Map.fromList [ (_ec_safeguard ec,ec) | ec<-ecs ]
-
-prj_encrypted_copy_map :: EncrypedCopyMap -> REP__EncrypedCopyMap
-prj_encrypted_copy_map mp = REP__EncrypedCopyMap [ ec | (_,ec)<-Map.toList mp ]
-
-defaultConfiguration :: Settings -> Configuration
-defaultConfiguration stgs =
-  Configuration
-    { _cfg_settings = stgs
-    , _cfg_triggers = Map.empty
-    }
-
-
 inj_safeguard :: REP__Safeguard -> ParserWithErrs Safeguard
 inj_safeguard = return . safeguard . _sg_names
 
@@ -216,8 +171,6 @@
         }
 
 
-
-
 inj_PrivateKey :: REP__PrivateKey -> ParserWithErrs PrivateKey
 inj_PrivateKey REP__PrivateKey{..} =
     return
@@ -296,26 +249,173 @@
 
     same b b' = comparing xf b b' == EQ
 
-instance ToJSONKey Safeguard where
-  toJSONKey = ToJSONKeyText f g
-    where
-      f = T.pack . printSafeguard
-      g = text . T.pack . printSafeguard
 
-instance ToJSONKey Name where
-  toJSONKey = ToJSONKeyText f g
-    where
-      f = T.pack . _name
-      g = text . T.pack . _name
-
-instance ToJSONKey TriggerID where
-  toJSONKey = ToJSONKeyText f g
-    where
-      f = _TriggerID
-      g = text . _TriggerID
-
 $(generateAPITools keystoreSchema
                    [ enumTool
-                   , jsonTool
+                   , jsonTool'
                    , lensTool
                    ])
+
+
+instance ToJSON KeyStore where
+  toJSON = toJSON . toKeyStore_
+
+instance FromJSON KeyStore where
+  parseJSON = fmap fromKeyStore_ . parseJSON
+
+instance FromJSONWithErrs KeyStore where
+  parseJSONWithErrs = fmap fromKeyStore_ . parseJSONWithErrs
+
+
+data KeyStore =
+  KeyStore
+    { _ks_config :: Configuration
+    , _ks_keymap :: KeyMap
+    }
+  deriving (Show,Eq)
+
+toKeyStore_ :: KeyStore -> KeyStore_
+toKeyStore_ KeyStore{..} =
+  KeyStore_
+    { _z_ks_config = toConfiguration_ _ks_config
+    , _z_ks_keymap = toKeyMap_        _ks_keymap
+    }
+
+fromKeyStore_ :: KeyStore_ -> KeyStore
+fromKeyStore_ KeyStore_{..} =
+  KeyStore
+    { _ks_config = fromConfiguration_ _z_ks_config
+    , _ks_keymap = fromKeyMap_        _z_ks_keymap
+    }
+
+emptyKeyStore :: Configuration -> KeyStore
+emptyKeyStore cfg =
+  KeyStore
+      { _ks_config = cfg
+      , _ks_keymap = emptyKeyMap
+      }
+
+
+data Configuration =
+  Configuration
+    { _cfg_settings :: Settings
+    , _cfg_triggers :: TriggerMap
+    }
+  deriving (Show,Eq)
+
+toConfiguration_ :: Configuration -> Configuration_
+toConfiguration_ Configuration{..} =
+  Configuration_
+    { _z_cfg_settings =               _cfg_settings
+    , _z_cfg_triggers = toTriggerMap_ _cfg_triggers
+    }
+
+fromConfiguration_ :: Configuration_ -> Configuration
+fromConfiguration_ Configuration_{..} =
+  Configuration
+    { _cfg_settings =                 _z_cfg_settings
+    , _cfg_triggers = fromTriggerMap_ _z_cfg_triggers
+    }
+
+defaultConfiguration :: Settings -> Configuration
+defaultConfiguration stgs =
+  Configuration
+    { _cfg_settings = stgs
+    , _cfg_triggers = Map.empty
+    }
+
+
+type TriggerMap = Map.Map TriggerID Trigger
+
+toTriggerMap_ :: TriggerMap -> TriggerMap_
+toTriggerMap_ mp = TriggerMap_ $ Map.elems mp
+
+fromTriggerMap_ :: TriggerMap_ -> TriggerMap
+fromTriggerMap_ TriggerMap_{..} = Map.fromList
+  [ (,) _trg_id trg
+    | trg@Trigger{..} <- _z_tmp_map
+    ]
+
+
+type KeyMap = Map.Map Name Key
+
+toKeyMap_ :: KeyMap -> KeyMap_
+toKeyMap_ mp = KeyMap_ $
+  [ NameKeyAssoc_ nm $ toKey_ ky
+    | (nm,ky) <- Map.assocs mp
+    ]
+
+fromKeyMap_ :: KeyMap_ -> KeyMap
+fromKeyMap_ mp_ = Map.fromList
+  [ (_z_nka_name,fromKey_ _z_nka_key)
+    | NameKeyAssoc_{..} <- _z_kmp_map mp_
+    ]
+
+emptyKeyMap :: KeyMap
+emptyKeyMap = Map.empty
+
+
+data Key =
+  Key
+    { _key_name          :: Name
+    , _key_comment       :: Comment
+    , _key_identity      :: Identity
+    , _key_is_binary     :: Bool
+    , _key_env_var       :: Maybe EnvVar
+    , _key_hash          :: Maybe Hash
+    , _key_public        :: Maybe PublicKey
+    , _key_secret_copies :: EncrypedCopyMap
+    , _key_clear_text    :: Maybe ClearText
+    , _key_clear_private :: Maybe PrivateKey
+    , _key_created_at    :: UTCTime
+    }
+  deriving (Show,Eq)
+
+toKey_ :: Key -> Key_
+toKey_ Key{..} =
+  Key_
+    { _z_key_name          =                   _key_name
+    , _z_key_comment       =                   _key_comment
+    , _z_key_identity      =                   _key_identity
+    , _z_key_is_binary     =                   _key_is_binary
+    , _z_key_env_var       =                   _key_env_var
+    , _z_key_hash          =                   _key_hash
+    , _z_key_public        =                   _key_public
+    , _z_key_secret_copies = toEncrypedCopyMap _key_secret_copies
+    , _z_key_clear_text    =                   _key_clear_text
+    , _z_key_clear_private =                   _key_clear_private
+    , _z_key_created_at    = UTC               _key_created_at
+    }
+
+fromKey_ :: Key_ -> Key
+fromKey_ Key_{..} =
+  Key
+    { _key_name          =                     _z_key_name
+    , _key_comment       =                     _z_key_comment
+    , _key_identity      =                     _z_key_identity
+    , _key_is_binary     =                     _z_key_is_binary
+    , _key_env_var       =                     _z_key_env_var
+    , _key_hash          =                     _z_key_hash
+    , _key_public        =                     _z_key_public
+    , _key_secret_copies = fromEncrypedCopyMap _z_key_secret_copies
+    , _key_clear_text    =                     _z_key_clear_text
+    , _key_clear_private =                     _z_key_clear_private
+    , _key_created_at    = _UTC                _z_key_created_at
+    }
+
+
+type EncrypedCopyMap = Map.Map Safeguard EncrypedCopy
+
+toEncrypedCopyMap :: EncrypedCopyMap -> EncrypedCopyMap_
+toEncrypedCopyMap mp = EncrypedCopyMap_ $ Map.elems mp
+
+fromEncrypedCopyMap :: EncrypedCopyMap_ -> EncrypedCopyMap
+fromEncrypedCopyMap EncrypedCopyMap_{..} = Map.fromList
+  [ (,) _ec_safeguard ec
+    | ec@EncrypedCopy{..} <- _z_ecm_map
+    ]
+
+
+L.makeLenses ''KeyStore
+L.makeLenses ''Configuration
+L.makeLenses ''Key
diff --git a/src/Data/KeyStore/Types/NameAndSafeguard.hs b/src/Data/KeyStore/Types/NameAndSafeguard.hs
--- a/src/Data/KeyStore/Types/NameAndSafeguard.hs
+++ b/src/Data/KeyStore/Types/NameAndSafeguard.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE StandaloneDeriving         #-}
 
 module Data.KeyStore.Types.NameAndSafeguard
     ( Name
@@ -13,15 +14,16 @@
     ) where
 
 import           Data.KeyStore.Types.E
+import           Data.Char
 import qualified Data.Set                       as Set
 import           Data.String
-import           Data.Char
 import qualified Control.Exception              as X
 
 newtype Name
     = Name            { _Name            :: String       }
     deriving (Eq,Ord,IsString,Read,Show)
 
+
 name :: String -> E Name
 name s =
     case all is_nm_char s of
@@ -41,7 +43,6 @@
         case parseSafeguard s of
           Left err -> X.throw err
           Right sg -> sg
-
 
 safeguard :: [Name] -> Safeguard
 safeguard = Safeguard . Set.fromList
diff --git a/src/Data/KeyStore/Types/PasswordStoreModel.hs b/src/Data/KeyStore/Types/PasswordStoreModel.hs
--- a/src/Data/KeyStore/Types/PasswordStoreModel.hs
+++ b/src/Data/KeyStore/Types/PasswordStoreModel.hs
@@ -18,54 +18,126 @@
 
 module Data.KeyStore.Types.PasswordStoreModel where
 
-import           Data.KeyStore.Types.PasswordStoreSchema
+import qualified Control.Lens               as L
 import           Data.Aeson
-import           Data.Aeson.Encoding
+import           Data.API.JSON
+import           Data.KeyStore.Types.PasswordStoreSchema
 import qualified Data.Map                                 as Map
 import           Data.API.Tools
-import           Data.API.JSON
+import           Data.Time
+import           Data.KeyStore.Types.UTC
 
 
 $(generate passwordStoreSchema)
+$(generateAPITools passwordStoreSchema
+                   [ enumTool
+                   , jsonTool'
+                   , lensTool
+                   ])
 
 
+instance ToJSON PasswordStore where
+  toJSON = toJSON . toPasswordStore_
+
+instance FromJSON PasswordStore where
+  parseJSON = fmap fromPasswordStore_ . parseJSON
+
+instance FromJSONWithErrs PasswordStore where
+  parseJSONWithErrs = fmap fromPasswordStore_ . parseJSONWithErrs
+
+
+data PasswordStore =
+  PasswordStore
+    { _ps_comment :: PasswordStoreComment
+    , _ps_map     :: PasswordMap
+    , _ps_setup   :: UTCTime
+    }
+  deriving (Show,Eq)
+
+toPasswordStore_ :: PasswordStore -> PasswordStore_
+toPasswordStore_ PasswordStore{..} =
+  PasswordStore_
+    { _z_ps_comment =                _ps_comment
+    , _z_ps_map     = toPasswordMap_ _ps_map
+    , _z_ps_setup   = UTC            _ps_setup
+    }
+
+fromPasswordStore_ :: PasswordStore_ -> PasswordStore
+fromPasswordStore_ PasswordStore_{..} =
+  PasswordStore
+    { _ps_comment =                  _z_ps_comment
+    , _ps_map     = fromPasswordMap_ _z_ps_map
+    , _ps_setup   = _UTC             _z_ps_setup
+    }
+
+
 -- The PasswordStre and SessionMap association lists are represented internally
 -- with maps.
 
 
 type PasswordMap = Map.Map PasswordName Password
 
-inj_pwmap :: REP__PasswordMap -> ParserWithErrs PasswordMap
-inj_pwmap (REP__PasswordMap as) =
-  return $ Map.fromList [ (_npa_name,_npa_password) | NamePasswordAssoc{..}<-as ]
+toPasswordMap_ :: PasswordMap -> PasswordMap_
+toPasswordMap_ mp = PasswordMap_ $
+  [ NamePasswordAssoc_ nm $ toPassword_ pw
+    | (nm,pw) <- Map.assocs mp
+    ]
 
-prj_pwmap :: PasswordMap -> REP__PasswordMap
-prj_pwmap mp = REP__PasswordMap [ NamePasswordAssoc nme pwd | (nme,pwd)<-Map.toList mp ]
+fromPasswordMap_ :: PasswordMap_ -> PasswordMap
+fromPasswordMap_ mp_ = Map.fromList
+  [ (_z_npa_name,fromPassword_ _z_npa_password)
+    | NamePasswordAssoc_{..} <- _z_pm_map mp_
+    ]
 
 
-type SessionMap = Map.Map SessionName Session
+data Password =
+  Password
+    { _pw_name        :: PasswordName
+    , _pw_text        :: PasswordText
+    , _pw_sessions    :: SessionMap
+    , _pw_isOneShot   :: Bool
+    , _pw_primed      :: Bool
+    , _pw_setup       :: UTCTime
+    }
+  deriving (Show,Eq)
 
-inj_snmap :: REP__SessionMap -> ParserWithErrs SessionMap
-inj_snmap (REP__SessionMap as) =
-  return $ Map.fromList [ (_spa_name,_spa_session) | SessionPasswordAssoc{..}<-as ]
+toPassword_ :: Password -> Password_
+toPassword_ Password{..} =
+  Password_
+    { _z_pw_name        =               _pw_name
+    , _z_pw_text        =               _pw_text
+    , _z_pw_sessions    = toSessionMap_ _pw_sessions
+    , _z_pw_isOneShot   =               _pw_isOneShot
+    , _z_pw_primed      =               _pw_primed
+    , _z_pw_setup       = UTC           _pw_setup
+    }
 
-prj_snmap :: SessionMap -> REP__SessionMap
-prj_snmap mp = REP__SessionMap [ SessionPasswordAssoc snm ssn | (snm,ssn)<-Map.toList mp ]
+fromPassword_ :: Password_ -> Password
+fromPassword_ Password_{..} =
+  Password
+    { _pw_name        =                 _z_pw_name
+    , _pw_text        =                 _z_pw_text
+    , _pw_sessions    = fromSessionMap_ _z_pw_sessions
+    , _pw_isOneShot   =                 _z_pw_isOneShot
+    , _pw_primed      =                 _z_pw_primed
+    , _pw_setup       = _UTC            _z_pw_setup
+    }
 
-instance ToJSONKey SessionName where
-  toJSONKey = ToJSONKeyText f g
-    where
-      f = _SessionName
-      g = text . _SessionName
 
-instance ToJSONKey PasswordName where
-  toJSONKey = ToJSONKeyText f g
-    where
-      f = _PasswordName
-      g = text . _PasswordName
+type SessionMap = Map.Map SessionName Session
 
-$(generateAPITools passwordStoreSchema
-                   [ enumTool
-                   , jsonTool
-                   , lensTool
-                   ])
+toSessionMap_ :: SessionMap -> SessionMap_
+toSessionMap_ mp = SessionMap_ $
+  [ SessionPasswordAssoc_ nm ssn
+    | (nm,ssn) <- Map.assocs mp
+    ]
+
+fromSessionMap_ :: SessionMap_ -> SessionMap
+fromSessionMap_ mp_ = Map.fromList
+  [ (_z_spa_name,_z_spa_session)
+    | SessionPasswordAssoc_{..} <- _z_smp_map mp_
+    ]
+
+
+L.makeLenses ''PasswordStore
+L.makeLenses ''Password
diff --git a/src/Data/KeyStore/Types/PasswordStoreSchema.hs b/src/Data/KeyStore/Types/PasswordStoreSchema.hs
--- a/src/Data/KeyStore/Types/PasswordStoreSchema.hs
+++ b/src/Data/KeyStore/Types/PasswordStoreSchema.hs
@@ -30,54 +30,72 @@
 passwordStoreChangelog :: APIChangelog
 (passwordStoreSchema, passwordStoreChangelog) = [apiWithChangelog|
 
-ps :: PasswordStore
+//
+// External Representation Only
+//
+
+// The builtin support for map-like types introduced in Aeson 1.0 has broken
+// the mechanism for representing Map in this schema. In order to minimise the
+// disruption and preserve the existing schema representation we have renamed
+// all of the types in the schema that contain Map types. In the model these
+// types are reconstructed just as they would have been in previous KeyStore
+// editions and mapping functions have been introduced to convert between the
+// two representations. The PasswordStore gets read with this representation,
+// matching the representation of past keystore packages and gets
+// converted into the internal type representation (with the maps) that the
+// rest of the keystore code base expects.
+
+z_ps :: PasswordStore_
     = record
         comment     :: PasswordStoreComment
-        map         :: PasswordMap
-        setup       :: utc
+        map         :: PasswordMap_
+        setup       :: UTC
 
-pm :: PasswordMap
+z_pm :: PasswordMap_
     // the password map, represented internally with a Map
     // from PasswordName to Password
     = record
-        map         :: [NamePasswordAssoc]
-    with inj_pwmap, prj_pwmap
+        map         :: [NamePasswordAssoc_]
 
-npa :: NamePasswordAssoc
+z_npa :: NamePasswordAssoc_
     = record
         name        :: PasswordName
-        password    :: Password
+        password    :: Password_
 
-pw  :: Password
+z_pw  :: Password_
     // passwords may be simple, or be a collection of 'sessions',
     // one of which is selected
     = record
         name        :: PasswordName
         text        :: PasswordText
-        sessions    :: SessionMap
+        sessions    :: SessionMap_
         isOneShot   :: Bool
         primed      :: boolean
-        setup       :: utc
+        setup       :: UTC
 
-smp :: SessionMap
+z_smp :: SessionMap_
     // collections of sessions are represented internally as a Map
     // from SessionName to PasswordText
     = record
-        map         :: [SessionPasswordAssoc]
-    with inj_snmap, prj_snmap
+        map         :: [SessionPasswordAssoc_]
 
-spa :: SessionPasswordAssoc
+z_spa :: SessionPasswordAssoc_
     = record
         name        :: SessionName
         session     :: Session
 
+
+//
+// Classic Schema Definitions
+//
+
 ssn :: Session
     // a session just consists of a password and the stup time
     = record
         name        :: SessionName
         password    :: PasswordText
         isOneShot   :: Bool
-        setup       :: utc
+        setup       :: UTC
 
 pwsc :: PasswordStoreComment
     // a short comment on the PasswordStore
diff --git a/src/Data/KeyStore/Types/Schema.hs b/src/Data/KeyStore/Types/Schema.hs
--- a/src/Data/KeyStore/Types/Schema.hs
+++ b/src/Data/KeyStore/Types/Schema.hs
@@ -29,49 +29,47 @@
 keystoreSchema    :: API
 keystoreChangelog :: APIChangelog
 (keystoreSchema, keystoreChangelog) = [apiWithChangelog|
-ks :: KeyStore
-    // the keystore
-    = record
-        config :: Configuration
-        keymap :: KeyMap
 
-cfg :: Configuration
-    = record
-        settings :: Settings
-        triggers :: TriggerMap
+//
+// External Representation Only
+//
 
-tmp :: TriggerMap
-    = record
-        map :: [Trigger]
-    with inj_trigger_map, prj_trigger_map
+// The builtin support for map-like types introduced in Aeson 1.0 has broken
+// the mechanism for representing Map in this schema. In order to minimise the
+// disruption and preserve the existing schema representation we have renamed
+// all of the types in the schema that contain Map types. In the model these
+// types are reconstructed just as they would have been in previous KeyStore
+// editions and mapping functions have been introduced to convert between the
+// two representations. The KeyStore gets read with this representation,
+// matching the representation of past keystore packages and gets converted
+//  into the internal type representation (with the maps) that the rest of the
+// keystore code base expects.
 
-trg :: Trigger
+z_ks :: KeyStore_
+    // the keystore
     = record
-        id       :: TriggerID
-        pattern  :: Pattern
-        settings :: Settings
+        config :: Configuration_
+        keymap :: KeyMap_
 
-stgs :: Settings
+z_cfg :: Configuration_
     = record
-        'json'   :: json
-    with inj_settings, prj_settings
+        settings :: Settings
+        triggers :: TriggerMap_
 
-tja :: TextJsonAssoc
+z_tmp :: TriggerMap_
     = record
-        id  :: SettingID
-        key :: json
+        map :: [Trigger]
 
-kmp :: KeyMap
+z_kmp :: KeyMap_
     = record
-        map :: [NameKeyAssoc]
-    with inj_keymap, prj_keymap
+        map :: [NameKeyAssoc_]
 
-nka :: NameKeyAssoc
+z_nka :: NameKeyAssoc_
     = record
         name :: Name
-        key  :: Key
+        key  :: Key_
 
-key :: Key
+z_key :: Key_
     = record
         name          :: Name
         comment       :: Comment
@@ -80,11 +78,31 @@
         env_var       :: ? EnvVar
         hash          :: ? Hash
         public        :: ? PublicKey
-        secret_copies :: EncrypedCopyMap
+        secret_copies :: EncrypedCopyMap_
         clear_text    :: ? ClearText
         clear_private :: ? PrivateKey
-        created_at    :: utc
+        created_at    :: UTC
 
+z_ecm :: EncrypedCopyMap_
+    = record
+        map :: [EncrypedCopy]
+
+
+//
+// Classic Schema Definitions
+//
+
+trg :: Trigger
+    = record
+        id       :: TriggerID
+        pattern  :: Pattern
+        settings :: Settings
+
+stgs :: Settings
+    = record
+        'json'   :: json
+    with inj_settings, prj_settings
+
 hash :: Hash
     = record
         description :: HashDescription
@@ -98,11 +116,6 @@
           width_octets :: Octets
           salt_octets  :: Octets
           salt         :: Salt
-
-ecm :: EncrypedCopyMap
-    = record
-        map :: [EncrypedCopy]
-    with inj_encrypted_copy_map, prj_encrypted_copy_map
 
 ec :: EncrypedCopy
     = record
diff --git a/src/Data/KeyStore/Types/UTC.hs b/src/Data/KeyStore/Types/UTC.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/KeyStore/Types/UTC.hs
@@ -0,0 +1,43 @@
+{-# LANGUAGE TemplateHaskell            #-}
+{-# LANGUAGE QuasiQuotes                #-}
+
+module Data.KeyStore.Types.UTC (UTC(..)) where
+
+import           Data.Aeson
+import           Data.API.JSON
+import           Data.Time
+import           Text.RE.Replace
+import           Text.RE.TDFA.String
+
+
+-- | package time has some variation in the formatting of second fractions
+-- in %Q (http://hackage.haskell.org/package/time-1.8.0.2/changelog) so we
+-- we will standardise on ".xxx"
+newtype UTC = UTC { _UTC :: UTCTime }
+  deriving (Eq,Show)
+
+
+instance ToJSON UTC where
+  toJSON = toJSON . formatUTC
+
+instance FromJSON UTC where
+  parseJSON = fmap UTC . parseJSON
+
+instance FromJSONWithErrs UTC where
+  parseJSONWithErrs = fmap UTC . parseJSONWithErrs
+
+
+formatUTC :: UTC -> String
+formatUTC (UTC u) = cleanup $ formatTime defaultTimeLocale fmt u
+  where
+    fmt = iso8601DateFormat $ Just "%H:%M:%S%QZ"
+
+cleanup :: String -> String
+cleanup s = case (captureTextMaybe [cp|u|] mtch,captureTextMaybe [cp|q|] mtch) of
+    (Just u,Nothing) -> u ++ ".000Z"
+    (Just u,Just q ) -> u ++ "." ++ rjust q ++ "Z"
+    _ -> s
+  where
+    mtch = s ?=~ [re|^${u}([T0-9:-]+)(.${q}([0-9]*))?Z$|]
+
+    rjust ds = take 3 $ ds ++ "000"
