diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index b91f7d5f175a32a49a5ed0788a87146d9b86c3f3..86befd80730159ff40ac5f0ca7e0ae766784ea4b 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -23,7 +23,7 @@ unit-tests:
 vulnerability-scan:
   stage: "test"
   script:
-    - "sed -i 's/undefined/\"unundefined\"/' morph/grid/local/secrets/users.nix"
+    - "sed -i 's/undefined/\"unundefined\"/' morph/grid/local/public-keys/users.nix"
     - "ci-tools/vulnerability-scan security-report.json"
     - "ci-tools/count-vulnerabilities <security-report.json"
   artifacts:
diff --git a/docs/source/ops/generating-keys.rst b/docs/source/ops/generating-keys.rst
index 47a1f4e91a876ac1919252c099654886f0bd128a..42364aa02e2dfd7f69604bced7c70333e0f377b6 100644
--- a/docs/source/ops/generating-keys.rst
+++ b/docs/source/ops/generating-keys.rst
@@ -1,9 +1,9 @@
 Generating keys
 ===============
 
-There's an example ``secrets`` repo in ``morph/grid/local/secrets``.
+There are example ``public-keys`` and ``private-keys`` repos in ``morph/grid/local/``.
 ``<grid>/config.json`` has the paths for the key files for the respective grid.
-Create a symlink named ``secrets`` to your secret key repository for the deployment you are working on.
+Create symlinks named ``public-keys`` and ``private-keys`` to your secret key repositories for the deployment you are working on.
 
 
 Stripe
@@ -55,22 +55,6 @@ Move the three .pem files into the payment's server ``/var/lib/letsencrypt/live/
 Monitoring VPN
 ``````````````
 
-Create Wireguard VPN key pairs in ``secrets/monitoringvpn/`` or where you have them.
-
-``tools/create-vpn-keys.sh`` holds a script to rotate all VPN keys at once::
+Create all of the Wireguard VPN keys for a grid::
 
   ./tools/create-vpn-keys.sh morph/grid/testing/grid.nix
-
-Or do it manually::
-
-  cd secrets/monitoringvpn
-  for i in 1 11 12 13 ; do
-    wg genkey | tee 172.23.23.${i}.key | wg pubkey > 172.23.23.${i}.pub
-  done
-
-  ln -s 172.23.23.1.key server.key
-  ln -s 172.23.23.1.pub server.pub
-
-And a shared VPN key for "post-quantum resistance"::
-
-  wg genpsk > preshared.key
diff --git a/morph/README.rst b/morph/README.rst
index 12472518ad8e061764d6812694c306e87553c843..f43926119b6609fcd0c746dcc1113822b5244e5a 100644
--- a/morph/README.rst
+++ b/morph/README.rst
@@ -42,8 +42,8 @@ grid
 
 Specific grid definitions live in subdirectories beneath this directory.
 
-secrets
-~~~~~~~
+private-keys
+~~~~~~~~~~~~
 
 This must be created and populated before the grid can be built or deployed.
 
@@ -55,10 +55,18 @@ This path is **ignored** by git.
 The intended workflow is that the secrets will be maintained on secure storage and a symlink to the correct location created here.
 This keeps the secrets themselves out of the git working tree as an extra protection against unintentionally committing them.
 
-An exception is the ``secrets`` directory in the ``local`` morph grid:
+An exception is the ``private-keys`` directory in the ``local`` morph grid:
 That directory is fully populated, provided as an example, and mostly: not very secret.
 Do not deploy these keys to machines reachable via the internet.
 
+public-keys
+~~~~~~~~~~~
+
+This must be created and populated before the grid can be built or deployed.
+
+This directory contains any public key material necessary for operation of the grid.
+This includes the public keys corresponding to any private keys held in ``private-keys``.
+
 config.json
 ~~~~~~~~~~~
 
diff --git a/morph/grid/local/README.rst b/morph/grid/local/README.rst
index f899c4975bab131e969acc79e8b39dee139b1554..d30d8766a4ef5a8db228ef38374330734e69cba7 100644
--- a/morph/grid/local/README.rst
+++ b/morph/grid/local/README.rst
@@ -37,7 +37,7 @@ Use the local development environment
 
 6. Add your SSH key to ``users.nix`` so you'll be able to log in after deploying the new configuration::
 
-    $EDITOR secrets/users.nix
+    $EDITOR public-keys/users.nix
 
 7. Then, build and deploy our software to the Vagrant VMs::
 
diff --git a/morph/grid/local/Vagrantfile b/morph/grid/local/Vagrantfile
index fd374a2cc26da63262a16fdf462e235fc5523fd1..a2890b8a63304d37002076b5804f2b322207160e 100644
--- a/morph/grid/local/Vagrantfile
+++ b/morph/grid/local/Vagrantfile
@@ -15,7 +15,7 @@ Vagrant.configure("2") do |config|
     config.vm.box_check_update = false
     config.vm.network "private_network", ip: "192.168.67.21"
     # Add self signed SSL key for zkap-issuer:
-    config.vm.provision "file", source: "secrets/payments-localdev-ssl", destination: "/tmp/payments-localdev-ssl"
+    config.vm.provision "file", source: "private-keys/payments-localdev-ssl", destination: "/tmp/payments-localdev-ssl"
     config.vm.provision "shell", inline: "sudo mkdir -p /var/lib/letsencrypt/live/payments.localdev/"
     config.vm.provision "shell", inline: "sudo mv /tmp/payments-localdev-ssl/* /var/lib/letsencrypt/live/payments.localdev/"
   end
diff --git a/tools/create-vpn-keys.sh b/tools/create-vpn-keys.sh
index e092a8ced698bd3a3bb2d4acc3ca07a3a8e6032d..c81225ec340db38d551e9d0c6c13d7bd44e21a4d 100755
--- a/tools/create-vpn-keys.sh
+++ b/tools/create-vpn-keys.sh
@@ -4,7 +4,7 @@
 # Parameters:
 #   file: path to grid.nix of morph deployment
 #
-# Output: Key files for all monitoring VPN hosts in secrets/monitoringvpn
+# Output: Key files for all monitoring VPN hosts in {private,public}-keys/monitoringvpn
 #         relative to the grid.nix
 #
 # The server key will also be symlinked to server.{key,pub}.
@@ -19,7 +19,8 @@ if [[ $# -ne 1 ]]; then
 fi
 
 SRC=$(dirname $0)
-VPN_SECRETS=$(dirname $1)/secrets/monitoringvpn
+VPN_SECRETS=$(dirname $1)/private-keys/monitoringvpn
+VPN_PUBLIC=$(dirname $1)/public-keys/monitoringvpn
 
 CONFIG=$(nix-instantiate --strict --json --eval "${SRC}"/get-vpn-config.nix --arg pathToGrid "${1}")
 
@@ -27,14 +28,15 @@ MONITORING_IPS=$(echo $CONFIG | jp --unquoted "join(' ', clientIPs)")
 VPNSERVER_IP=$(echo $CONFIG | jp --unquoted "serverIP")
 
 mkdir -p "${VPN_SECRETS}"
+mkdir -p "${VPN_PUBLIC}"
 
 for i in $MONITORING_IPS $VPNSERVER_IP; do
-  wg genkey | tee "${VPN_SECRETS}"/${i}.key | wg pubkey > "${VPN_SECRETS}"/${i}.pub
+  wg genkey | tee "${VPN_SECRETS}"/${i}.key | wg pubkey > "${VPN_PUBLIC}"/${i}.pub
 done
 
 wg genpsk > "${VPN_SECRETS}"/preshared.key
 
 ln -fs $VPNSERVER_IP.key "${VPN_SECRETS}"/server.key
-ln -fs $VPNSERVER_IP.pub "${VPN_SECRETS}"/server.pub
+ln -fs $VPNSERVER_IP.pub "${VPN_PUBLIC}"/server.pub
 
 # EOF