diff --git a/changelog b/changelog
--- a/changelog
+++ b/changelog
@@ -28,3 +28,13 @@
 	* Write Haddock annotations for Sections module.
 	* Tidy cabal file
 	* Revise readme and cabal documentation
+
+0.5.0.0 Chris Dornan <chrisd@irisconnect.co.uk> 2014-07-27
+	* expose getKeystore, getState, getCtxState, putCtxState in Data.KeyStore.IO
+	* add proxy arguments to verifyKeystore & locateKeys in Data.KeyStore.Sections
+	* opened up the export of Data.KeyStore.Types
+	* added getSettingsOpt' to Data.KeyStore.KS.Opt
+	* Fix #1, (section, key and host prefixes)
+
+0.5.0.1 Chris Dornan <chrisd@irisconnect.co.uk> 2014-07-28
+	* fix default sectionPWEnvVar in Sections class
diff --git a/examples/deploy/deploy.hs b/examples/deploy/deploy.hs
--- a/examples/deploy/deploy.hs
+++ b/examples/deploy/deploy.hs
@@ -57,7 +57,7 @@
 sign_ks ic = signKeystore ic sections >>= B.writeFile ks_mac_fp
 
 verify_ks :: Bool -> IC -> IO ()
-verify_ks fatal ic = chk =<< catch (B.readFile ks_mac_fp >>= verifyKeystore ic) hdl
+verify_ks fatal ic = chk =<< catch (B.readFile ks_mac_fp >>= verifyKeystore ic sections) hdl
   where
     chk True              = return ()
     chk False | fatal     = error msg
diff --git a/keystore.cabal b/keystore.cabal
--- a/keystore.cabal
+++ b/keystore.cabal
@@ -1,5 +1,5 @@
 Name:                   keystore
-Version:                0.4.0.0
+Version:                0.5.0.1
 Synopsis:               Managing stores of secret things
 Homepage:               http://github.com/cdornan/keystore
 Author:                 Chris Dornan
@@ -160,7 +160,6 @@
         crypto-random          >= 0.0.7             ,
         aeson                  >= 0.6.2             ,
         aeson-pretty           >= 0.7               ,
-        attoparsec             >= 0.10.4.0          ,
         base                   >= 4                 ,
         base64-bytestring      >= 1.0               ,
         byteable               >= 0.1               ,
diff --git a/src/Data/KeyStore/CLI.hs b/src/Data/KeyStore/CLI.hs
--- a/src/Data/KeyStore/CLI.hs
+++ b/src/Data/KeyStore/CLI.hs
@@ -18,7 +18,7 @@
 
 
 version :: String
-version = "0.4.0.0"
+version = "0.5.0.1"
 
 cli :: IO ()
 cli = parseCLI >>= command Nothing
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
@@ -62,6 +62,10 @@
     , verify
     , verify_
     , run
+    , getKeystore
+    , getState
+    , getCtxState
+    , putCtxState
     ) where
 
 import           Data.KeyStore.IO.IC
@@ -105,7 +109,7 @@
 -- context to be cached between calls to these access functions.
 instanceCtx :: CtxParams -> IO IC
 instanceCtx cp =
- do ctx_st <- get $ instanceCtx_ cp
+ do ctx_st <- getCtxState $ instanceCtx_ cp
     IC cp . Just <$> newIORef ctx_st
 
 -- | This functional method will generate an IC that will not cache any
@@ -268,7 +272,7 @@
 
 -- | Return all of the keys in the keystore.
 keys :: IC -> IO [Key]
-keys ic = Map.elems . _ks_keymap <$> get_keystore ic
+keys ic = Map.elems . _ks_keymap <$> getKeystore ic
 
 -- | Delete a list of keys from the keystore.
 deleteKeys :: IC -> [Name] -> IO ()
@@ -345,14 +349,14 @@
 -- debug logging and errors.
 run :: IC -> KS a -> IO a
 run ic p =
- do (ctx,st0) <- get ic
+ do (ctx,st0) <- getCtxState ic
     st1 <- scan_env ctx st0
     let msg         = "[Keystore: " ++ ctx_store ctx ++"]\n"
         (e,st2,les) = run_ ctx st1 $ debugLog msg >> p
     r <- e2io e
     mapM_ (logit ctx) les
     st' <- backup_env ctx st2
-    put ic ctx st'
+    putCtxState ic ctx st'
     return r
 
 scan_env :: Ctx -> State -> IO State
@@ -371,20 +375,20 @@
   where
     (e,st',les') = run_ ctx st0 backupKeysKS
 
-get_keystore :: IC -> IO KeyStore
-get_keystore ic = st_keystore <$> get_state ic
+getKeystore :: IC -> IO KeyStore
+getKeystore ic = st_keystore <$> getState ic
 
-get_state :: IC -> IO State
-get_state ic = snd <$> get ic
+getState :: IC -> IO State
+getState ic = snd <$> getCtxState ic
 
-get :: IC -> IO (Ctx,State)
-get IC{..} =
+getCtxState :: IC -> IO (Ctx,State)
+getCtxState IC{..} =
     case ic_cache of
       Nothing -> determineCtx ic_ctx_params
       Just rf -> readIORef rf
 
-put :: IC -> Ctx -> State -> IO ()
-put IC{..} ctx st =
+putCtxState :: IC -> Ctx -> State -> IO ()
+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
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
@@ -7,9 +7,11 @@
     , OptEnum(..)
     , opt_enum
     , getSettingsOpt
+    , getSettingsOpt'
     , setSettingsOpt
     , opt__debug_enabled
     , opt__verify_enabled
+    , opt__sections_fix
     , opt__backup_keys
     , opt__hash_comment
     , opt__hash_prf
@@ -39,6 +41,7 @@
 import           Data.Maybe
 import           Data.Char
 import           Text.Printf
+import           Control.Applicative
 
 
 data Opt a
@@ -58,9 +61,11 @@
     deriving Show
 
 getSettingsOpt :: Opt a -> Settings -> a
-getSettingsOpt Opt{..} (Settings hm) =
-                maybe opt_default opt_from $ HM.lookup (optName opt_enum) hm
+getSettingsOpt opt = maybe (opt_default opt) id . getSettingsOpt' opt
 
+getSettingsOpt' :: Opt a -> Settings -> Maybe a
+getSettingsOpt' Opt{..} (Settings hm) = opt_from <$> HM.lookup (optName opt_enum) hm
+
 setSettingsOpt :: Opt a -> a -> Settings -> Settings
 setSettingsOpt Opt{..} x (Settings hm) =
                   Settings $ HM.insert (optName opt_enum) (opt_to x) hm
@@ -72,6 +77,9 @@
 opt__verify_enabled       :: Opt Bool
 opt__verify_enabled       = bool_opt vfy_help                            False       Verify__enabled
 
+opt__sections_fix         :: Opt Bool
+opt__sections_fix         = bool_opt sfx_help                            False       Sections__fix
+
 opt__backup_keys          :: Opt [Name]
 opt__backup_keys          = backup_opt bku_help                                      Backup__keys
 
@@ -106,6 +114,7 @@
 data OptEnum
     = Debug__enabled
     | Verify__enabled
+    | Sections__fix
     | Backup__keys
     | Hash__comment
     | Hash__prf
@@ -125,6 +134,7 @@
     case enm of
       Debug__enabled        -> Opt_ opt__debug_enabled
       Verify__enabled       -> Opt_ opt__verify_enabled
+      Sections__fix         -> Opt_ opt__sections_fix
       Backup__keys          -> Opt_ opt__backup_keys
       Hash__comment         -> Opt_ opt__hash_comment
       Hash__prf             -> Opt_ opt__hash_prf
@@ -258,7 +268,7 @@
 
     typ   = T.intercalate "|" $ map shw [minBound..maxBound]
 
-dbg_help, vfy_help, bku_help, hcm_help, hpr_help, hit_help, hwd_help,
+dbg_help, vfy_help, sfx_help, bku_help, hcm_help, hpr_help, hit_help, hwd_help,
     hna_help, ccy_help, cpr_help, cit_help, cna_help :: [T.Text]
 
 dbg_help =
@@ -269,6 +279,11 @@
   , "in which the secret text loaded from environment"
   , "variables is checked against the stored MACs."
   , "These checks can consume a lot of compute time."
+  ]
+sfx_help =
+  [ "Set when a 'Sections' keystore has been fixed so that"
+  , "section, key and host names no longer contrained to avoid"
+  , "prefixes."
   ]
 bku_help =
   [ "Controls the default keys that will be used to make secret copies"
diff --git a/src/Data/KeyStore/Sections.hs b/src/Data/KeyStore/Sections.hs
--- a/src/Data/KeyStore/Sections.hs
+++ b/src/Data/KeyStore/Sections.hs
@@ -31,17 +31,23 @@
   where
 
 import           Data.KeyStore.IO
+import           Data.KeyStore.KS
 import qualified Data.Text                      as T
 import qualified Data.ByteString.Char8          as B
 import qualified Data.ByteString.Lazy.Char8     as LBS
 import qualified Data.Aeson                     as A
 import qualified Data.HashMap.Strict            as HM
 import qualified Data.Vector                    as V
+import qualified Data.Map                       as Map
 import           Data.Maybe
 import           Data.List
+import           Data.Char
 import           Data.Ord
+import           Data.String
 import           Data.Monoid
+import           Control.Lens
 import           Control.Applicative
+import           Control.Monad
 import           Text.Printf
 import           System.FilePath
 import           Safe
@@ -106,7 +112,7 @@
 
   describeSection     s = "The '" ++ encode s ++ "' Section."
 
-  sectionPWEnvVar       = EnvVar . T.pack . ("KEY_" ++) . _name . passwordName
+  sectionPWEnvVar       = EnvVar . T.pack . ("KEY_pw_" ++) . encode
 
 
 -- | Sections are used to hold the top (master) key for the keystore,
@@ -150,7 +156,7 @@
 -- procedure.
 initialise :: Sections h s k => CtxParams -> KeyPredicate h s k -> IO ()
 initialise cp kp = do
-    stgs <- scs kp Nothing
+    stgs <- setSettingsOpt opt__sections_fix True <$> scs kp Nothing
     newKeyStore (the_keystore cp) stgs
     ic <- instanceCtx cp
     mapM_ (mks kp ic) [minBound..maxBound]
@@ -165,26 +171,34 @@
 
 -- | Rotate in a set of keys spwecified by the predicate.
 rotate :: Sections h s k => IC -> KeyPredicate h s k -> IO ()
-rotate ic kp = sequence_ [ rotate' ic mb_h s k | (mb_h,s,k)<-host_keys++non_host_keys, kp mb_h s k ]
+rotate ic kp = reformat ic' $ sequence_ [ rotate' ic mb_h s k | (mb_h,s,k)<-host_keys++non_host_keys, kp mb_h s k ]
   where
     host_keys     = [ (Just h ,s,k) | k<-[minBound..maxBound], Just isp<-[keyIsHostIndexed k], h<-[minBound..maxBound], isp h, let s = key_section h k ]
     non_host_keys = [ (Nothing,s,k) | k<-[minBound..maxBound], Nothing <-[keyIsHostIndexed k], s<-[minBound..maxBound], keyIsInSection k s             ]
 
+    ic' = kp_RFT kp ic
+
 -- | Retrieve the keys for a given host from the store. Note that the whole history for the given key is returned.
 -- Note also that the secret text may not be present if it si not accessible (depnding upon hwich section passwords
 -- are correctly bound in the process environment). Note also that the 'Retrieve' diagnostic should not fail if a
 -- coherent model has been ddefined for 'Sections'.
 retrieve :: Sections h s k => IC -> h -> k -> IO (Retrieve [Key])
-retrieve ic h k = either (return . Left) (\nm->Right <$> locateKeys ic nm) $ keyName h k
+retrieve ic h k = reformat ic' $ either (return . Left) (\nm->Right <$> locate_keys ic' nm) $ keyName h k
+  where
+    ic' = h_RFT h ic
 
 -- | Sign the keystore. (Requites the password for the signing section to be correctly
 -- bound in the environment)
 signKeystore :: Sections h s k => IC -> SECTIONS h s k -> IO B.ByteString
-signKeystore ic scn = B.readFile (the_keystore $ ic_ctx_params ic) >>= sign_ ic (sgn_nme $ signing_key scn)
+signKeystore ic scn = reformat ic' $ B.readFile (the_keystore $ ic_ctx_params ic) >>= sign_ ic (sgn_nme $ signing_key scn)
+  where
+    ic' = scn_RFT scn ic
 
 -- Verify that the signature for a keystore matches the keystore.
-verifyKeystore :: IC -> B.ByteString -> IO Bool
-verifyKeystore ic sig = B.readFile (the_keystore $ ic_ctx_params ic) >>= flip (verify_ ic) sig
+verifyKeystore :: Sections h s k => IC -> SECTIONS h s k -> B.ByteString -> IO Bool
+verifyKeystore ic scn sig = reformat ic' $ B.readFile (the_keystore $ ic_ctx_params ic) >>= flip (verify_ ic) sig
+  where
+    ic' = scn_RFT scn ic
 
 -- | A predicate specifying all of the keys in the store.
 noKeys :: KeyPredicate h s k
@@ -254,28 +268,37 @@
 -- to work the password for the top section (or the passwords for all of the sections
 -- must be bound if the store does not maintain a top key).
 secretKeySummary :: Sections h s k => IC -> SECTIONS h s k -> IO T.Text
-secretKeySummary ic scn = T.unlines <$> mapM f (sections scn)
+secretKeySummary ic scn = reformat ic' $ T.unlines <$> mapM f (sections scn)
   where
     f s = do
       sec <- T.pack . B.unpack <$> (showSecret ic False $ passwordName s)
       return $ T.concat ["export ",_EnvVar $ sectionPWEnvVar s,"=",sec]
 
+    ic' = scn_RFT scn ic
+
 -- | List a shell script for storing the public signing key for the store.
 publicKeySummary :: Sections h s k => IC -> SECTIONS h s k -> FilePath -> IO T.Text
-publicKeySummary ic scn fp = f <$> showPublic ic True (sgn_nme $ signing_key scn)
+publicKeySummary ic scn fp = reformat ic' $ f <$> showPublic ic True (sgn_nme $ signing_key scn)
   where
     f b = T.pack $ "echo '" ++ B.unpack b ++ "' >" ++ fp ++ "\n"
 
+    ic' = scn_RFT scn ic
+
 -- | List all of the keys that have the given name as their prefix. If the
 -- generic name of a key is given then it will list the complete history for
 -- the key, the current (or most recent) entry first.
-locateKeys :: IC -> Name -> IO [Key]
-locateKeys ic nm = sortBy (flip $ comparing _key_name) . filter yup <$> keys ic
+locateKeys :: Sections h s k => IC -> SECTIONS h s k -> Name -> IO [Key]
+locateKeys ic scn nm = locate_keys ic' nm
   where
+    ic' = scn_RFT scn ic
+
+locate_keys :: Sections h s k => REFORMAT h s k -> Name -> IO [Key]
+locate_keys ic' nm = reformat ic' $ sortBy (flip $ comparing _key_name) . filter yup <$> keys ic
+  where
     yup     = isp . _key_name
     isp nm' = nm_s `isPrefixOf` _name nm'
-
     nm_s    = _name nm
+    ic      = _REFORMAT ic'
 
 -- | Return the genertic name for a given key thst is used by the specified
 -- host, returning a failure diagnostic if the host does not have such a key
@@ -304,7 +327,7 @@
 
 -- | The name of the key that stores the password for a given sections.
 passwordName :: Sections h s k => s -> Name
-passwordName s = name' $ "pw_"   ++ encode s
+passwordName s = name' $ "/pw/"   ++ encode s
 
 fmt :: Code a => (a->Bool) -> String
 fmt p  = unwords [ encode h | h<-[minBound..maxBound], p h ]
@@ -385,18 +408,18 @@
 backup_password ic s sv_s = secureKey ic (passwordName s) $ safeguard [sve_nme sv_s]
 
 key_nme :: Sections h s k => Maybe h -> s -> k -> Name
-key_nme mb_h s k = name' $ encode s ++ "_" ++ encode k ++ hst_sfx
+key_nme mb_h s k = name' $ encode s ++ "/" ++ encode k ++ hst_sfx
   where
-    hst_sfx = maybe "" (\h -> "_" ++ encode h) mb_h
+    hst_sfx = maybe "" (\h -> "/" ++ encode h) mb_h
 
 sgn_nme :: Sections h s k => s -> Name
-sgn_nme s = name' $ encode s ++ "_keystore_signing_key"
+sgn_nme s = name' $ encode s ++ "/keystore_signing_key"
 
 sve_nme :: Sections h s k => s -> Name
-sve_nme s = name' $ "save_" ++ encode s
+sve_nme s = name' $ "/save/" ++ encode s
 
 scn_pattern :: Sections h s k => s -> Pattern
-scn_pattern s = pattern $ "^" ++ encode s ++ "_.*"
+scn_pattern s = pattern $ "^" ++ encode s ++ "/.*"
 
 unique_nme :: IC -> Name -> IO Name
 unique_nme ic nm =
@@ -411,10 +434,7 @@
     c_nms = [ nm | i<-[length nms+1..], let nm=nname i nm0, nm `notElem` nms ]
 
     nname :: Int -> Name -> Name
-    nname i nm_ = name' $ _name nm_ ++ printf "_%03d" i
-
-name' :: String -> Name
-name' = either (error.show) id . name
+    nname i nm_ = name' $ _name nm_ ++ printf "/%03d" i
 
 the_keystore :: CtxParams -> FilePath
 the_keystore = maybe "keystore.json" id . cp_store
@@ -432,3 +452,213 @@
       }
   where
     fp sfx = sd </> encode k ++ sfx
+
+
+--------------------------------------------------------------------------------
+--
+-- Regormating the KeyStore Names to Allow Prefixes (#3)
+--
+--------------------------------------------------------------------------------
+
+
+reformat :: Sections h s k => REFORMAT h s k -> IO a -> IO a
+reformat rft@(REFORMAT ic) p = reformat_ic (encoding rft) ic >> p
+
+-- Proxy city!
+
+data REFORMAT h s k = REFORMAT { _REFORMAT :: IC }
+
+data CODE a = CODE
+
+scn_RFT :: SECTIONS     h s k -> IC -> REFORMAT h s k
+kp_RFT  :: KeyPredicate h s k -> IC -> REFORMAT h s k
+h_RFT   ::              h     -> IC -> REFORMAT h s k
+
+scn_RFT _ ic = REFORMAT ic
+kp_RFT  _ ic = REFORMAT ic
+h_RFT   _ ic = REFORMAT ic
+
+reformat_ic :: Encoding -> IC -> IO ()
+reformat_ic enc ic = do
+  (ctx,st) <- getCtxState ic
+  putCtxState ic ctx $
+    st { st_keystore = reformat_keystore enc $ st_keystore st }
+
+reformat_keystore :: Encoding -> KeyStore -> KeyStore
+reformat_keystore enc ks =
+  case getSettingsOpt opt__sections_fix $ _cfg_settings $ _ks_config ks of
+    True  -> ks
+    False -> over ks_config (reformat_config  enc) $
+             over ks_keymap (reformat_key_map enc) ks
+
+reformat_config :: Encoding -> Configuration -> Configuration
+reformat_config enc =
+  over cfg_settings (setSettingsOpt opt__sections_fix True) .
+  over cfg_settings (reformat_settings enc) .
+  over cfg_triggers (reformat_triggers enc)
+
+reformat_triggers :: Encoding -> TriggerMap -> TriggerMap
+reformat_triggers enc = Map.map $
+  over trg_pattern  (reformat_pattern  enc) .
+  over trg_settings (reformat_settings enc)
+
+reformat_settings :: Encoding -> Settings -> Settings
+reformat_settings enc stgs =
+  case getSettingsOpt' opt__backup_keys stgs of
+    Nothing  -> stgs
+    Just nms -> setSettingsOpt opt__backup_keys (map (reformat_name enc) nms) stgs
+
+reformat_pattern :: Encoding -> Pattern -> Pattern
+reformat_pattern enc pat = maybe oops id $ run_munch (m_pattern enc) $ _pat_string pat
+  where
+    oops = error $ "reformat_pattern: bad pattern format: " ++ _pat_string pat
+
+reformat_key_map :: Encoding -> KeyMap -> KeyMap
+reformat_key_map enc km = Map.fromList [ (reformat_name enc nm,r_ky ky) | (nm,ky)<-Map.toList km ]
+  where
+    r_ky =
+      over key_name          (reformat_name enc) .
+      over key_secret_copies (reformat_ecm  enc)
+
+reformat_ecm :: Encoding -> EncrypedCopyMap -> EncrypedCopyMap
+reformat_ecm enc ecm = Map.fromList [ (reformat_sg enc sg,r_ec ec) | (sg,ec)<-Map.toList ecm ]
+  where
+    r_ec = over ec_safeguard (reformat_sg enc)
+
+reformat_sg :: Encoding -> Safeguard -> Safeguard
+reformat_sg enc = safeguard . map (reformat_name enc) . safeguardKeys
+
+reformat_name :: Encoding -> Name -> Name
+reformat_name enc nm = maybe oops id $ run_munch (m_name enc) $ _name nm
+  where
+    oops = error $ "reformat_name: bad name format: " ++ _name nm
+
+m_pattern :: Encoding -> Munch Pattern
+m_pattern enc = do
+  munch_ "^"
+  s <- enc_s enc
+  munch_ "_.*"
+  return $ fromString $ "^" ++ s ++ "/.*"
+
+m_name, m_save, m_pw, m_section :: Encoding -> Munch Name
+
+m_name enc = m_save enc <|> m_pw enc <|> m_section enc
+
+m_save enc = do
+  munch_ "save_"
+  s <- enc_s enc
+  return $ name' $ "/save/" ++ s
+
+m_pw enc = do
+  munch_ "pw_"
+  s <- enc_s enc
+  return $ name' $ "/pw/" ++ s
+
+m_section enc = do
+  s <- enc_s enc
+  m_section_signing enc s <|> m_section_key enc s
+
+m_section_key, m_section_signing  :: Encoding -> String -> Munch Name
+
+m_section_signing _ s = do
+  munch_ "_keystore_signing_key"
+  return $ name' $ s ++ "/keystore_signing_key"
+
+m_section_key enc s = do
+  munch_ "_"
+  k <- enc_k enc
+  m_section_key_host enc s k <|> m_section_key_vrn enc s k
+
+m_section_key_vrn, m_section_key_host :: Encoding -> String -> String -> Munch Name
+
+m_section_key_vrn _ s k = do
+  munch_ "_"
+  v <- munch_vrn
+  return $ name' $ s ++"/" ++ k ++ "/" ++ v
+
+m_section_key_host enc s k = do
+  munch_ "_"
+  h <- enc_h enc
+  munch_ "_"
+  v <- munch_vrn
+  return $ name' $ s ++"/" ++ k ++ "/" ++ h ++ "/" ++ v
+
+munch_vrn :: Munch String
+munch_vrn = do
+  c1 <- munch1 isDigit
+  c2 <- munch1 isDigit
+  c3 <- munch1 isDigit
+  return [c1,c2,c3]
+
+-- Capturing the host, section and key encodings in a nice convenient
+-- monotype that we can pass around.
+
+data Encoding =
+  Encoding
+    { enc_h, enc_s, enc_k :: Munch String
+    }
+
+encoding :: Sections h s k => REFORMAT h s k -> Encoding
+encoding rft =
+  Encoding
+    { enc_h = code_m $ host_c    rft
+    , enc_s = code_m $ section_c rft
+    , enc_k = code_m $ key_c     rft
+    }
+  where
+    host_c      :: Sections h s k => REFORMAT h s k -> CODE h
+    host_c    _ = CODE
+
+    section_c   :: Sections h s k => REFORMAT h s k -> CODE s
+    section_c _ = CODE
+
+    key_c       :: Sections h s k => REFORMAT h s k -> CODE k
+    key_c     _ = CODE
+
+code_m :: Code a => CODE a -> Munch String
+code_m c = foldr (<|>) empty $ [ munch $ encode x | x<-bds c ]
+  where
+    bds :: Code a => CODE a -> [a]
+    bds _ = [minBound..maxBound]
+
+-- our Munch Monad
+
+newtype Munch a = Munch { _Munch :: String -> Maybe (a,String) }
+
+instance Functor Munch where
+  fmap f m = m >>= \x -> return $ f x
+
+instance Applicative Munch where
+  pure  = return
+  (<*>) = ap
+
+instance Alternative Munch where
+  empty     = Munch $ const Nothing
+  (<|>) x y = Munch $ \s -> _Munch x s <|> _Munch y s
+
+instance Monad Munch where
+  return x  = Munch $ \s -> Just (x,s)
+  (>>=) m f = Munch $ \s -> _Munch m s >>= \(x,s') -> _Munch (f x) s'
+
+run_munch :: Munch a -> String -> Maybe a
+run_munch (Munch f) str = case f str of
+  Just (x,"") -> Just x
+  _           -> Nothing
+
+munch1 :: (Char->Bool) -> Munch Char
+munch1 p = Munch $ \str -> case str of
+  c:t | p c -> Just (c,t)
+  _         -> Nothing
+
+munch_ :: String -> Munch ()
+munch_ s = const () <$> munch s
+
+munch :: String -> Munch String
+munch str_p = Munch $ \str -> case str_p `isPrefixOf` str of
+  True  -> Just (str_p,drop (length str_p) str)
+  False -> Nothing
+
+--------------------------------------------------------------------------------
+
+name' :: String -> Name
+name' = either (error.show) id . name
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
@@ -27,77 +27,11 @@
 -- marked down in <https://github.com/cdornan/keystore/blob/master/schema.md>.
 
 module Data.KeyStore.Types
-    ( KeyStore(..)
-    , ks_keymap
-    , ks_config
-    , Configuration(..)
-    , TriggerMap
-    , Trigger(..)
-    , Settings(..)
-    , cfg_settings
-    , cfg_triggers
-    , TextJsonAssoc(..)
-    , KeyMap
-    , NameKeyAssoc(..)
-    , Key(..)
-    , key_name
-    , key_comment
-    , key_identity
-    , key_is_binary
-    , key_env_var
-    , key_hash
-    , key_public
-    , key_secret_copies
-    , key_clear_text
-    , key_clear_private
-    , key_created_at
-    , Hash(..)
-    , HashDescription(..)
-    , EncrypedCopyMap
-    , EncrypedCopy(..)
-    , EncrypedCopyData(..)
-    , RSASecretData(..)
-    , AESSecretData(..)
-    , PublicKey(..)
-    , PrivateKey(..)
-    , Cipher(..)
-    , _text_Cipher
-    , HashPRF(..)
-    , _text_HashPRF
-    , EncryptionKey(..)
-    , FragmentID(..)
-    , Pattern(..)
-    , Iterations(..)
-    , Octets(..)
-    , Identity(..)
-    , SettingID(..)
-    , TriggerID(..)
-    , Comment(..)
-    , EnvVar(..)
-    , ClearText(..)
-    , Salt(..)
-    , IV(..)
-    , HashData(..)
-    , AESKey(..)
-    , SecretData(..)
-    , RSAEncryptedKey(..)
-    , RSASecretBytes(..)
-    , RSASignature(..)
-    , EncryptionPacket(..)
-    , SignaturePacket(..)
-    , Void(..)
-    , Dirctn(..)
-    , void_
-    , pattern
-    , defaultSettings
-    , checkSettingsCollisions
-    , emptyKeyStore
-    , emptyKeyMap
-    , defaultConfiguration
-    , pbkdf
-    , keyWidth
+    ( module Data.KeyStore.Types
     , module Data.KeyStore.Types.NameAndSafeguard
     , module Data.KeyStore.Types.E
+    , PublicKey(..)
+    , PrivateKey(..)
     ) where
 
 import           Data.KeyStore.Types.Schema
