diff --git a/data/secmod_denom/.gitkeep b/data/secmod_denom/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/data/secmod_signkey/.gitkeep b/data/secmod_signkey/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/data/secmod_signkey/sm_key.priv b/data/secmod_signkey/sm_key.priv
new file mode 100644
index 00000000..41a3df39
--- /dev/null
+++ b/data/secmod_signkey/sm_key.priv
@@ -0,0 +1 @@
+¼‘ÑŸ¸ÿœ¦$–ñá•8œ­êýÉïÿBÖ¿JŒ˜T{
\ No newline at end of file
diff --git a/data/secmod_signkey/sm_key.pub b/data/secmod_signkey/sm_key.pub
new file mode 100644
index 00000000..502ae977
--- /dev/null
+++ b/data/secmod_signkey/sm_key.pub
@@ -0,0 +1 @@
+.áš+„G°ÑÔƒQÌÍq ÞNŽ¯´[ßÔÒÍYL	
\ No newline at end of file
diff --git a/src/devices.ml b/src/devices.ml
index 673a8113..6a0b792f 100644
--- a/src/devices.ml
+++ b/src/devices.ml
@@ -1,22 +1,127 @@
-(* TODO KV store *)
-
 type env = {
   caqti_switch: Caqti_miou.Switch.t;
   db_uri: Uri.t;
 }
 
+let db_connection : (env, Caqti_miou.connection) Vif.Device.device =
+  let finally (module Conn : Caqti_miou.CONNECTION) = Conn.disconnect () in
+  Vif.Device.v ~name:"db_connection" ~finally []
+  @@ fun { caqti_switch; db_uri } ->
+  match Caqti_miou_unix.connect ~sw:caqti_switch db_uri with
+  | Error err ->
+      Fmt.failwith "Database connection failure: %a." Caqti_error.pp err
+  | Ok conn -> (
+      match Pg.preflight conn with
+      | Error err ->
+          Fmt.failwith "Database preflight failure: %a." Caqti_error.pp err
+      | Ok () -> conn)
+
+(* TODO KV store *)
+
 module Secmod_signkey = struct
   type t = {
     sm_key: Signkey.t;
     keys: Signkey.t list;
   }
 
-  let v =
-    let finally _key = () in
-    Vif.Device.v ~name:"secmod_signkey" ~finally [] @@ fun (_env : env) ->
+  let dir = Fpath.(v "data" / "secmod_signkey")
+
+  let read_eddsa_key_files fname =
+    let open Syntax in
+    let open Bos.OS in
+    let open Crypto in
+    let pub = Fpath.(dir / fname) |> Fpath.set_ext "pub" in
+    let priv = Fpath.(dir / fname) in
+    let* b0 = File.exists pub in
+    let* b1 = File.exists priv in
+    match (b0, b1) with
+    | true, true ->
+        let* pub = File.read pub in
+        let* priv = File.read priv in
+        let pub = EddsaPublicKey.of_octets pub in
+        let priv = EddsaPrivateKey.of_octets priv in
+        Ok (Some (pub, priv))
+    | false, false -> Ok None
+    | _, _ -> Error (`Msg "secmod_signkey: invalid local file state.")
+
+  let write_eddsa_key_files fname signkey =
+    let open Syntax in
+    let open Bos.OS in
+    let open Crypto in
+    let pub_file = Fpath.(dir / fname) |> Fpath.set_ext "pub" in
+    let priv_file = Fpath.(dir / fname) in
+    let pub = EddsaPublicKey.to_octets signkey.Signkey.pub in
+    let priv = EddsaPrivateKey.to_octets signkey.priv in
+    let* () = File.write pub_file pub in
+    let* () = File.write priv_file priv in
+    Ok ()
+
+  let write_local_keys t =
+    let open Syntax in
+    let* () = write_eddsa_key_files "sm_key" t.sm_key in
+    let keys = List.mapi (fun i key -> (string_of_int i, key)) t.keys in
+    let* () = list_iter (fun (s, key) -> write_eddsa_key_files s key) keys in
+    Ok ()
+
+  let load_local_keys conn =
+    let open Syntax in
+    let load s =
+      let* opt = read_eddsa_key_files s in
+      match opt with
+      | None -> Ok None
+      | Some (pub, priv) -> (
+          let* opt = Pg.lookup_signing_key conn pub in
+          match opt with
+          | None ->
+              Fmt.error_msg
+                "secmod_signkey error: no associtaed metadata found in \
+                 database for key `%s`."
+                s
+          | Some (stamp_start, stamp_expire, stamp_end) ->
+              let master_sig = None in
+              Ok
+                (Some
+                   Signkey.
+                     {
+                       pub;
+                       priv;
+                       stamp_start;
+                       stamp_expire;
+                       stamp_end;
+                       master_sig;
+                     }))
+    in
+    let* sm_key = load "sm_key" in
+    let* key_0 = load "0" in
+    match (sm_key, key_0) with
+    | None, None -> Ok None
+    | Some sm_key, Some key_0 ->
+        let keys = [ key_0 ] in
+        Ok (Some { sm_key; keys })
+    | _, _ -> Error (`Msg "secmod_signkey: invalid local file state.")
+
+  let generate_fresh_keys () =
     let sm_key = Signkey.generate () in
     let keys = [ Signkey.generate () ] in
     { sm_key; keys }
+
+  let v =
+    let finally _key = () in
+    Vif.Device.v ~name:"secmod_signkey" ~finally
+      [ Vif.Device.value db_connection ]
+    @@ fun conn (_env : env) ->
+    match load_local_keys conn with
+    | Ok None ->
+        Fmt.pr "secmod_signkey: generate_fresh_keys@.";
+        let t = generate_fresh_keys () in
+        write_local_keys t |> Result.get_ok;
+        t
+    | Ok (Some v) ->
+        Fmt.pr "secmod_signkey: loaded local keys@.";
+        v
+    | Error _ ->
+        (* TODO pp error *)
+        Fmt.failwith "secmod_signkey init failure."
 end
 
 module Secmod_denom = struct
@@ -35,16 +140,3 @@ end
 
 let secmod_signkey = Secmod_signkey.v
 let secmod_denom = Secmod_denom.v
-
-let db_connection : (env, Caqti_miou.connection) Vif.Device.device =
-  let finally (module Conn : Caqti_miou.CONNECTION) = Conn.disconnect () in
-  Vif.Device.v ~name:"db_connection" ~finally []
-  @@ fun { caqti_switch; db_uri } ->
-  match Caqti_miou_unix.connect ~sw:caqti_switch db_uri with
-  | Error err ->
-      Fmt.failwith "Database connection failure: %a." Caqti_error.pp err
-  | Ok conn -> (
-      match Pg.preflight conn with
-      | Error err ->
-          Fmt.failwith "Database preflight failure: %a." Caqti_error.pp err
-      | Ok () -> conn)
diff --git a/src/management.ml b/src/management.ml
index cb90dd15..90d69bdb 100644
--- a/src/management.ml
+++ b/src/management.ml
@@ -54,7 +54,7 @@ let mk_future_denom denom_key_signf
     }
 
 let mk_future_signkey signkey_signf
-    ({ pub; stamp_start; stamp_expire; stamp_end; sign= _; master_sig= _ } :
+    ({ pub; priv= _; stamp_start; stamp_expire; stamp_end; master_sig= _ } :
       Signkey.t) =
   let signkey_secmod_sig =
     let open Bin_type in
@@ -83,12 +83,20 @@ let mk_future_keys_response (secmod_signkey : Secmod_signkey.t)
   let future_denoms =
     secmod_denom.keys
     |> List.filter (fun k -> Option.is_none k.Denomination.master_sig)
-    |> List.map (mk_future_denom secmod_denom.sm_key.Signkey.sign)
+    |> List.map (fun denom ->
+        let signf s =
+          Crypto.EddsaSignature.sign ~key:secmod_denom.sm_key.Signkey.priv s
+        in
+        mk_future_denom signf denom)
   in
   let future_signkeys =
     secmod_signkey.keys
     |> List.filter (fun k -> Option.is_none k.Signkey.master_sig)
-    |> List.map (mk_future_signkey secmod_signkey.sm_key.sign)
+    |> List.map (fun signkey ->
+        let signf s =
+          Crypto.EddsaSignature.sign ~key:secmod_denom.sm_key.Signkey.priv s
+        in
+        mk_future_signkey signf signkey)
   in
   let master_pub = Config.Exchange.master_public_key in
   let denom_secmod_public_key = secmod_denom.sm_key.pub in
diff --git a/src/mte.ml b/src/mte.ml
index 44ae36a0..9cf40473 100644
--- a/src/mte.ml
+++ b/src/mte.ml
@@ -129,7 +129,7 @@ let () =
   in
   let devices =
     Vif.Devices.
-      [ Devices.secmod_signkey; Devices.secmod_denom; Devices.db_connection ]
+      [ Devices.db_connection; Devices.secmod_signkey; Devices.secmod_denom ]
   in
   let middlewares = Vif.Middlewares.[] in
   Vif.run ~cfg ~devices ~middlewares routes env
diff --git a/src/pg.ml b/src/pg.ml
index a174b100..098dfc52 100644
--- a/src/pg.ml
+++ b/src/pg.ml
@@ -96,7 +96,7 @@ let activate_signing_key =
        expire_legal, master_sig) VALUES ($1, $2, $3, $4, $5)"
   in
   fun (module Conn : CONN)
-    Signkey.{ pub; stamp_start; stamp_expire; stamp_end; master_sig; sign= _ }
+    Signkey.{ pub; priv= _; stamp_start; stamp_expire; stamp_end; master_sig }
   ->
     (* TODO master_sig *)
     let master_sig = master_sig |> Option.get in
diff --git a/src/signkey.ml b/src/signkey.ml
index c4cfe477..2d958a33 100644
--- a/src/signkey.ml
+++ b/src/signkey.ml
@@ -4,10 +4,10 @@ open Crypto
    not sur how to handle master_sig initialization *)
 type t = {
   pub: EddsaPublicKey.t;
+  priv: EddsaPrivateKey.t;
   stamp_start: Ptime.t;
   stamp_expire: Ptime.t;
   stamp_end: Ptime.t;
-  sign: string -> EddsaSignature.t;
   (* signature of this key by offline master key *)
   master_sig: EddsaSignature.t option;
 }
@@ -25,6 +25,5 @@ let generate () =
   in
   let stamp_end = stamp_expire in
   let priv, pub = Mirage_crypto_ec.Ed25519.generate () in
-  let sign s = EddsaSignature.sign ~key:priv s in
   let master_sig = None in
-  { pub; stamp_start; stamp_expire; stamp_end; master_sig; sign }
+  { pub; priv; stamp_start; stamp_expire; stamp_end; master_sig }
