diff --git a/ci-tools/known_hosts.production b/ci-tools/known_hosts.production
new file mode 100644
index 0000000000000000000000000000000000000000..88e5696c47a6a5583e0eb20e3c77f82bc46bda8e
--- /dev/null
+++ b/ci-tools/known_hosts.production
@@ -0,0 +1,7 @@
+monitoring.private.storage ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGvKv2y+IAL4+oDnX7Cm5G9QuADBHUj9OxzLX0okf6hF
+payments.private.storage ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJBlyFTJyN+VDlzGWANKqBlXeexlX/xTpp6gb5sUlA9U
+storage001.private.storage ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILQojjGVvmjZfDcrlec8ZmpbzMEeHd4+t4DJq1R/NUXw
+storage002.private.storage ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKDWqK7FBzT4L1eoIU/iaEZNZxq3Jr613PmK2nbAXFs2
+storage003.private.storage ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHobJpQVv9GaTv8Xh9CGlL7BL5yKLxCiD3ZDdVTyt0Ep
+storage004.private.storage ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJy96VEPp617ewxdkt+8ZgWcYkLxlVG/C7bZAq0ULH+z
+storage005.private.storage ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKOgJBoER0lX2Rx8UIfv/3MVJXNFn9RldYmpU+EqAc9H
diff --git a/ci-tools/known_hosts.staging b/ci-tools/known_hosts.staging
new file mode 100644
index 0000000000000000000000000000000000000000..2a015656e4c21498f2fe152723888046d9341c1a
--- /dev/null
+++ b/ci-tools/known_hosts.staging
@@ -0,0 +1,3 @@
+monitoring.privatestorage-staging.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINI9kvEBaOMvpWqcFH+6nFvRriBECKB4RFShdPiIMkk9
+payments.privatestorage-staging.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK0eO/01VFwdoZzpclrmu656eaMkE19BaxtDdkkFHMa8
+storage001.privatestorage-staging.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFP8L6OHCxq9XFd8ME8ZrCbmO5dGZDPH8I5dm0AwSGiN
diff --git a/ci-tools/update-grid-servers b/ci-tools/update-grid-servers
index b11bc6f49af98e263ad610392849144353fa49ea..0d0195262a8ef25e28d7f5c0d5b4ca05439c002f 100755
--- a/ci-tools/update-grid-servers
+++ b/ci-tools/update-grid-servers
@@ -8,6 +8,10 @@
 
 set -euxo pipefail
 
+# Find the location of this script so we can refer to data files with a known
+# relative location.
+HERE=$(dirname $0)
+
 # Get the path to the ssh key which authorizes us to deliver this
 # notification.
 DEPLOY_KEY=$1
@@ -21,13 +25,24 @@ shift
 
 # Tell one server to update itself.
 update_one_node() {
+    grid_name=$1
+    shift
+
     deploy_key=$1
     shift
 
     node=$1
     shift
 
-    ssh -i "${deploy_key}" "deployment@${node}"
+    # Avoid both the "host key unknown" prompt and the possibility for a
+    # man-in-the-middle attack (on every single deploy!) by referring to a
+    # pre-initialized known hosts file for this grid.
+    #
+    # Then use the specified deploy key to authenticate as the deployment user
+    # and trigger the update on the host.  There's no command here because the
+    # deployment key is restricted *only* the deloyment update command and the
+    # ssh server will supply that command itself.
+    ssh -o "UserKnownHostsFile=${HERE}/known_hosts.${grid_name}" -i "${deploy_key}" "deployment@${node}"
 }
 
 # Tell all servers belonging to one grid to update themselves.
@@ -65,7 +80,7 @@ update_grid_nodes() {
 	    # This isn't a server, it's part of the morph configuration.
 	    continue
 	fi
-	update_one_node "${deploy_key}" "${node}.${domain}"
+	update_one_node "${gridname}" "${deploy_key}" "${node}.${domain}"
     done
 }
 
diff --git a/nixos/modules/deployment.nix b/nixos/modules/deployment.nix
index 4c3a9dd0b8fa16e204495269616e09a1e715ad6b..b0a5e3c4c761d188922a076643fcd3a25a4b81f0 100755
--- a/nixos/modules/deployment.nix
+++ b/nixos/modules/deployment.nix
@@ -11,13 +11,7 @@ let
     # `restrict` means "disable all the things" then `command` means "but
     # enable running this one command" (the client does not have to supply the
     # command; if they authenticate, this is the command that will run).
-    # environment lets us pass an environment variable into the process
-    # started by the given command.  It only works because we configured our
-    # sshd to allow this particular variable through.  By passing this value,
-    # we can pin nixpkgs in the executed command to the same version
-    # configured for use here.  It might be better if we just had a channel
-    # the system could be configured with ... but we don't at the moment.
-    "restrict,environment=\"NIXPKGS_FOR_MORPH=${pkgs.path}\",command=\"${command} ${gridName}\" ${authorizedKey}";
+    "restrict,command=\"${command} ${gridName}\" ${authorizedKey}";
 in {
   options = {
     services.private-storage.deployment.authorizedKey = lib.mkOption {
@@ -50,10 +44,6 @@ in {
       ];
     };
 
-    services.openssh.extraConfig = ''
-      PermitUserEnvironment=NIXPKGS_FOR_MORPH
-    '';
-
     # Create a one-time service that will set up an ssh key that allows the
     # deployment user to authorize as root to perform the system update with
     # `morph deploy`.
diff --git a/nixos/modules/update-deployment b/nixos/modules/update-deployment
index 19599a4aa7ac2ec7bbb7e160ec1b37a8493b4a62..d8d32ff64eb52123be448ed598d00ab2bc1850da 100755
--- a/nixos/modules/update-deployment
+++ b/nixos/modules/update-deployment
@@ -75,12 +75,15 @@ EOF
 # Make sure known_hosts has the host key in it.
 ssh -o StrictHostKeyChecking=no "$(hostname).$(domainname)" ":"
 
-# Set nixpkgs to our preferred version for the morph build.  The NIX_PATH
-# environment variable itself receives special treatment by some parts of the
-# system (especially those parts leading up to the execution of this script)
-# so we pass the desired information through a different variable and then
-# shuffle it into the right place here, just before it is needed.
-export NIX_PATH="nixpkgs=$NIXPKGS_FOR_MORPH"
+# Set nixpkgs to our preferred version for the morph build.  Annoyingly, we
+# can't just use nixpkgs-2105.nix as our nixpkgs because some code (in morph,
+# at least) wants <nixpkgs> to be a fully-resolved path to a nixpkgs tree.
+# For example, morph evaluated `import <nixpkgs/lib>` which would turn into
+# something like `import nixpkgs-2105.nix/lib` which is nonsense.
+#
+# So instead, import our nixpkgs which forces it to be instantiated in the
+# store, then ask for its path, then set NIX_PATH to that.
+export NIX_PATH="nixpkgs=$(nix eval "(import ${CHECKOUT}/nixpkgs-2105.nix { }).path")"
 
 # Attempt to update just this host.  Choose the morph grid definition matching
 # the grid we belong to and limit the morph deployment update to the host
@@ -89,7 +92,9 @@ export NIX_PATH="nixpkgs=$NIXPKGS_FOR_MORPH"
 if morph deploy "${CHECKOUT}"/morph/grid/"${GRIDNAME}"/grid.nix switch --on "$(hostname)"; then
     # The deployment succeeded.  Record success along with context we pre-computed.
     echo "${LOG_MESSAGE} OK" >> ${HOME}/updates.txt
+    exit 0
 else
     # Oops.  Not so fortunate.  Record failure.
     echo "${LOG_MESSAGE} FAIL" >> ${HOME}/updates.txt
+    exit 1
 fi