How to move your secrets to a new laptop

Your dotfiles are in git, so a new machine is one clone away. Your secrets are not, and they shouldn't be: API tokens, the .env of every project, ~/.zshrc.local with your exports. The usual fix is to email them to yourself or drop them in a notes app “just for the move”. Those copies stay there for years. Here is a way to move them that leaves nothing behind.

First: what not to move at all

Some secrets are better replaced than copied:

  • SSH keys. Generate a new key on the new laptop and add it to GitHub and your servers. Then remove the old one.
  • Cloud access keys. Create a new key for the new machine where you can, and revoke the old one once you've switched.

Everything else, like API tokens, project .env files and local config with exports, has to move. That's what the steps below are for.

Move them with one-time links

  1. On the old laptop, create a secret from each file. One view, short expiry, with a passphrase. Don't type the passphrase into the command itself: shells save commands in history. read -rs PASSPHRASE asks for it without showing it and keeps it out of history. SECRETBOLT_API_KEY is a read/write API key from your dashboard:
    read -rs PASSPHRASE   # typed, not echoed, not saved in shell history
    curl -fsS https://secretbolt.io/api/v1/secrets \
      -H "Authorization: Bearer $SECRETBOLT_API_KEY" \
      --data-urlencode name=".zshrc.local" \
      --data-urlencode content@$HOME/.zshrc.local \
      --data-urlencode passphrase="$PASSPHRASE" \
      -d max_views=1 -d expires_in_hours=1

    Or paste the file's content into secretbolt.io in the browser.

  2. Get the link to the new laptop. Send it to yourself in any chat. Without the passphrase the link is useless, and after one view it's gone.
  3. On the new laptop, write it straight to the right file. The file is created readable only by you, and nothing passes through your terminal history. TOKEN is the last part of the link, and READ_ONLY_KEY is a read-only API key from your dashboard:
    read -rs PASSPHRASE
    (umask 077 && secret_json=$(curl -fsS \
      -H "Authorization: Bearer $READ_ONLY_KEY" \
      -H "X-Passphrase: $PASSPHRASE" \
      https://secretbolt.io/api/v1/secrets/$TOKEN) &&
      printf '%s' "$secret_json" | jq -j '.content' > ~/.zshrc.local)

    Prefer the browser? Open the link, copy the content, and paste it into the file in your editor rather than with echo in the terminal.

  4. Check the old copies are gone. After the view the secret is erased on our side. The event log shows when it was opened. If it says “viewed” and that wasn't you, rotate those keys.

Project .env files with direnv

If you use direnv, commit the .envrc and keep .env untracked. On the new machine, fetch the .env into the project folder as above and direnv loads it whenever you cd in. See Using with direnv in the docs.

Good habits

  • One secret per file: it's easier to see what has been moved.
  • Keep the old laptop until everything works on the new one, then wipe it.
  • Don't put secrets into your dotfiles repo, even a private one. “Private” is not the same as “encrypted”.

Move your first secret free