From 99ec4d85cbd9f39a952c736dbe3f5f4938bd5130 Mon Sep 17 00:00:00 2001 From: Max Novak Date: Sat, 10 Oct 2026 20:36:35 +0000 Subject: [PATCH] Finish SSH signing setup and add git defaults setup.sh turned on SSH commit signing but set no allowed signers file, so git log --show-signature printed an error instead of verifying. It now writes ~/.ssh/allowed_signers (from your git email and signing key) and points gpg.ssh.allowedSignersFile at it, unless you already have one. It also appends a Host * block to ~/.ssh/config with UseKeychain and AddKeysToAgent, so the key passphrase is asked for once, unless the file already sets UseKeychain. dotfiles/gitconfig gains newer defaults: histogram diffs, rebase autoStash and updateRefs, push.followTags, commit.verbose, branches sorted by recent commit, version-sorted tags, columns, and help.autocorrect=prompt. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/ci.yml | 3 ++- README.md | 4 +++- dotfiles/gitconfig | 15 +++++++++++++++ setup.sh | 41 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c08a746..c78d6bb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -63,7 +63,8 @@ jobs: brew list --formula --versions brew list --cask --versions for file in ~/.zprofile ~/.zshrc ~/.gitconfig ~/.config/ghostty/config \ - ~/.config/herdr/config.toml ~/.docker/config.json; do + ~/.config/herdr/config.toml ~/.docker/config.json ~/.ssh/config \ + ~/.ssh/allowed_signers; do echo "== $file" cat "$file" 2>/dev/null || echo "(missing)" done diff --git a/README.md b/README.md index b021ed9..1d2958a 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,8 @@ Want a different selection? Edit the [`Brewfile`](Brewfile) before running `./se - Adds a `config-file` line to `~/.config/ghostty/config` that loads [`dotfiles/ghostty`](dotfiles/ghostty), which makes **Cmd+K** clear the screen inside herdr and tmux too, and makes the left Option key work as Alt - Creates `~/.config/herdr/config.toml` from [`dotfiles/herdr.toml`](dotfiles/herdr.toml) if you don't have one, or adds the tab shortcut to the one you have - Adds an include to the top of `~/.gitconfig` that loads [`dotfiles/gitconfig`](dotfiles/gitconfig) -- Turns on commit signing with your SSH key, if you have one and haven't set up signing already +- Turns on commit signing with your SSH key, if you have one and haven't set up signing already, and lets git check those signatures (`git log --show-signature`) +- Adds a few lines to the end of `~/.ssh/config` so macOS asks for your SSH key's passphrase once and keeps it in the keychain - Lets the Homebrew `docker` CLI find the `compose` and `buildx` plugins If something in the `Brewfile` fails to install, the other steps still run and the failures are listed at the end. It never overwrites your existing files, and it's safe to run again: that's also how you install anything you add to the `Brewfile` later. Your own settings in `~/.zshrc` and `~/.gitconfig` still apply, and those in `~/.gitconfig` take precedence. The config is loaded from the cloned repo, so keep it where you cloned it. @@ -126,6 +127,7 @@ Installed by hand, since it isn't available through Homebrew: ```sh ssh-keygen -t ed25519 -C "you@example.com" +git config --global user.email "you@example.com" # if you haven't yet ./setup.sh # turns on signing gh ssh-key add ~/.ssh/id_ed25519.pub --type authentication # for git push over SSH gh ssh-key add ~/.ssh/id_ed25519.pub --type signing # "Verified" badge on GitHub diff --git a/dotfiles/gitconfig b/dotfiles/gitconfig index ec67bab..142cd2e 100644 --- a/dotfiles/gitconfig +++ b/dotfiles/gitconfig @@ -5,6 +5,7 @@ defaultBranch = main [push] autoSetupRemote = true + followTags = true # push annotated tags along with the commits [fetch] prune = true [rerere] @@ -13,6 +14,20 @@ conflictStyle = zdiff3 [diff] colorMoved = default + algorithm = histogram # clearer diffs when code moves around +[rebase] + autoStash = true # rebase with uncommitted changes + updateRefs = true # keep stacked branches in sync when rebasing +[commit] + verbose = true # show the diff while writing the commit message +[branch] + sort = -committerdate # git branch: most recent first +[tag] + sort = version:refname # git tag: v1.10 after v1.9 +[column] + ui = auto # list branches and tags in columns +[help] + autocorrect = prompt # offer to run the command you meant on a typo # Readable diffs (git-delta) [core] diff --git a/setup.sh b/setup.sh index 724bcea..3dd7f99 100755 --- a/setup.sh +++ b/setup.sh @@ -123,6 +123,47 @@ else note " ssh-keygen -t ed25519 -C \"you@example.com\"" fi +# Without an allowed signers file, git log --show-signature shows an error instead of "Good signature". +SIGNING_KEY="$(git config --global user.signingkey || true)" +[[ -f "${SIGNING_KEY/#\~/$HOME}" ]] && SIGNING_KEY="$(cat "${SIGNING_KEY/#\~/$HOME}")" +read -r KEY_TYPE KEY_DATA _ <<< "${SIGNING_KEY#key::}" || true +ALLOWED_SIGNERS="$(git config --global gpg.ssh.allowedSignersFile || true)" +GIT_EMAIL="$(git config --global user.email || true)" +if [[ "$(git config --global gpg.format || true)" != ssh || -z "${KEY_DATA:-}" ]]; then + : # not signing with an SSH key +elif [[ -n "$ALLOWED_SIGNERS" ]]; then + if grep -qF "$KEY_DATA" "${ALLOWED_SIGNERS/#\~/$HOME}" 2>/dev/null; then + note "signature verification already set up" + else + note "to verify your signatures, add your key to $ALLOWED_SIGNERS" + fi +elif [[ -z "$GIT_EMAIL" ]]; then + note "set your git email (see the end), then re-run ./setup.sh so git can verify your signatures" +else + ALLOWED_SIGNERS="$HOME/.ssh/allowed_signers" + if ! grep -qF "$KEY_DATA" "$ALLOWED_SIGNERS" 2>/dev/null; then + printf '%s namespaces="git" %s %s\n' "$GIT_EMAIL" "$KEY_TYPE" "$KEY_DATA" >> "$ALLOWED_SIGNERS" + fi + git config --global gpg.ssh.allowedSignersFile "$ALLOWED_SIGNERS" + note "git can verify your signatures now: git log --show-signature" +fi + +step "SSH config" +SSH_CONFIG="$HOME/.ssh/config" +if grep -qi '^[[:space:]]*UseKeychain' "$SSH_CONFIG" 2>/dev/null; then + note "already uses the macOS keychain" +else + [[ -d "$HOME/.ssh" ]] || mkdir -m 700 "$HOME/.ssh" + [[ -f "$SSH_CONFIG" ]] || (umask 077 && touch "$SSH_CONFIG") + { echo; printf '%s\n' \ + '# Added by developer-machine-setup: ask for SSH key passphrases once, then keep them in the keychain' \ + 'Host *' \ + ' IgnoreUnknown UseKeychain' \ + ' UseKeychain yes' \ + ' AddKeysToAgent yes'; } >> "$SSH_CONFIG" + note "added keychain settings to the end of $SSH_CONFIG" +fi + step "Docker CLI plugins (compose, buildx)" DOCKER_CONFIG_FILE="$HOME/.docker/config.json" PLUGIN_DIR="$HOMEBREW_PREFIX/lib/docker/cli-plugins"