diff --git a/ci-tools/update-nixpkgs b/ci-tools/update-nixpkgs
index 554ca17094dfbcc589d4510ff33ae2a07d4364c6..d8f0fbfa16fb3810115ef8a0510dadb56ebf95d6 100755
--- a/ci-tools/update-nixpkgs
+++ b/ci-tools/update-nixpkgs
@@ -1,8 +1,35 @@
 #!/usr/bin/env nix-shell
-#!nix-shell -i sh -p nixUnstable git curl
+#!nix-shell -i sh -p nixUnstable git openssh curl
+
+# ^^
+# we get nixUnstable for the diff-closures command, mostly.
+# we need git to commit and push our changes
+# we need openssh for ssh-agent to authenticate the push
+# we need curl to create the gitlab MR
 
 set -eux -o pipefail
 
+setup_ssh() {
+    # -s makes the output sh compatible, in case it can't detect this for
+    # itself.
+    eval $(ssh-agent -s)
+
+    # A GitLab CI/CD variable set for us to use.
+    ssh-add <(echo "${UPDATE_NIXPKGS_PRIVATE_SSHKEY_BASE64}" | base64 -d)
+
+    # We may not know the git/ssh server's host key yet.  In that case, learn
+    # it and proceed.
+    export GIT_SSH_COMMAND="ssh -o StrictHostKeyChecking=accept-new"
+}
+
+setup_git() {
+    git config --global user.email "update-bot@private.storage"
+    git config --global user.name "Update Bot"
+}
+
+setup_ssh()
+setup_git()
+
 TARGET_BRANCH="nixpkgs-upgrade-$(date +%Y-%m-%d)"
 
 echo '{}' > morph/grid/local/public-keys/users.nix