diff --git a/morph/grid/local/grid.nix b/morph/grid/local/grid.nix
index dccb3813500c52eb234a41e304b3b29b2f893428..64c83da55f8b0ca59db193038d4055a033964172 100644
--- a/morph/grid/local/grid.nix
+++ b/morph/grid/local/grid.nix
@@ -22,14 +22,13 @@ in lib.make-grid {
     nodeExporterTargets = [ "monitoring" "payments" "storage1" "storage2" ];
 
   in {
-    "payments" = lib.make-issuer (cfg // rec {
-      publicIPv4 = "192.168.67.21";
-      monitoringvpnIPv4 = "172.23.23.11";
-      hardware = import ./virtual-hardware.nix ({ inherit publicIPv4; });
-      stateVersion = "19.03";
-      inherit monitoringvpnKeyDir;
-      inherit sshUsers;
-    });
+    payments = rec {
+      imports = [
+        lib.issuer
+        (import ./virtual-hardware.nix ({ publicIPv4 = "192.168.67.21"; }))
+        (lib.customize-issuer cfg sshUsers monitoringvpnKeyDir "172.23.23.11" "19.03")
+      ];
+    };
 
     "storage1" = lib.make-testing (cfg // rec {
       publicIPv4 = "192.168.67.22";
diff --git a/morph/lib/customize-issuer.nix b/morph/lib/customize-issuer.nix
new file mode 100644
index 0000000000000000000000000000000000000000..a7e8271370aecc455e54db0c5652b5d3417d4b4e
--- /dev/null
+++ b/morph/lib/customize-issuer.nix
@@ -0,0 +1,24 @@
+cfg: sshUsers: monitoringvpnKeyDir: monitoringvpnIPv4: stateVersion: {
+  deployment.secrets = {
+    "ristretto-signing-key".source = cfg.ristrettoSigningKeyPath;
+    "stripe-secret-key".source = cfg.stripeSecretKeyPath;
+    "monitoringvpn-secret-key".source = "${monitoringvpnKeyDir}/${monitoringvpnIPv4}.key";
+    "monitoringvpn-preshared-key".source = "${monitoringvpnKeyDir}/preshared.key";
+  };
+
+  services.private-storage.sshUsers = sshUsers;
+  services.private-storage.monitoring.vpn.client = {
+    enable = true;
+    ip = monitoringvpnIPv4;
+    endpoint = cfg.monitoringvpnEndpoint;
+    endpointPublicKeyFile = "${monitoringvpnKeyDir}/server.pub";
+  };
+
+  services.private-storage-issuer = {
+    letsEncryptAdminEmail = cfg.letsEncryptAdminEmail;
+    domains = cfg.issuerDomains;
+    allowedChargeOrigins = cfg.allowedChargeOrigins;
+  };
+
+  system.stateVersion = "19.03";
+}
diff --git a/morph/lib/default.nix b/morph/lib/default.nix
index 95a3ee14e35f664886e5be55d9d206e1b5701610..7d28796d38e59a6c3a395130722983375d058583 100644
--- a/morph/lib/default.nix
+++ b/morph/lib/default.nix
@@ -6,4 +6,7 @@ rec {
   make-monitoring = import ./make-monitoring.nix;
 
   hardware-aws = import ./issuer-aws.nix;
+
+  issuer = import ./issuer.nix;
+  customize-issuer = import ./customize-issuer.nix;
 }
diff --git a/morph/lib/issuer.nix b/morph/lib/issuer.nix
new file mode 100644
index 0000000000000000000000000000000000000000..4312088448fa2f9f9e1de262376dd977df3340c6
--- /dev/null
+++ b/morph/lib/issuer.nix
@@ -0,0 +1,68 @@
+rec {
+  deployment = {
+    secrets = {
+      "ristretto-signing-key" = {
+        # source = ... fill this in ...
+        destination = "/run/keys/ristretto.signing-key";
+        owner.user = "root";
+        owner.group = "root";
+        permissions = "0400";
+        action = ["sudo" "systemctl" "restart" "zkapissuer.service"];
+      };
+      "stripe-secret-key" = {
+        # source = ... fill this in ...
+        destination = "/run/keys/stripe.secret-key";
+        owner.user = "root";
+        owner.group = "root";
+        permissions = "0400";
+        action = ["sudo" "systemctl" "restart" "zkapissuer.service"];
+      };
+
+      "monitoringvpn-secret-key" = {
+        # source = ... fill this in ...
+        destination = "/run/keys/monitoringvpn/client.key";
+        owner.user = "root";
+        owner.group = "root";
+        permissions = "0400";
+        action = ["sudo" "systemctl" "restart" "wireguard-monitoringvpn.service"];
+      };
+      "monitoringvpn-preshared-key" = {
+        # source = ... fill this in ...
+        destination = "/run/keys/monitoringvpn/preshared.key";
+        owner.user = "root";
+        owner.group = "root";
+        permissions = "0400";
+        action = ["sudo" "systemctl" "restart" "wireguard-monitoringvpn.service"];
+      };
+    };
+  };
+
+  imports = [
+    ../../nixos/modules/issuer.nix
+    ../../nixos/modules/monitoring/vpn/client.nix
+    ../../nixos/modules/monitoring/exporters/node.nix
+  ];
+
+  services.private-storage = {
+    # sshUsers = ...
+    monitoring.vpn.client = {
+      # enable = ...
+      # ip = ...
+      # endpoint = ...
+      # endpointPublicKeyFile = ...
+    };
+  };
+  services.private-storage-issuer = {
+    enable = true;
+    tls = true;
+    ristrettoSigningKeyPath = deployment.secrets.ristretto-signing-key.destination;
+    stripeSecretKeyPath = deployment.secrets.stripe-secret-key.destination;
+    database = "SQLite3";
+    databasePath = "/var/db/vouchers.sqlite3";
+    # inherit letsEncryptAdminEmail;
+    # domains = issuerDomains;
+    # inherit allowedChargeOrigins;
+  };
+
+  # system.stateVersion = stateVersion;
+}