git-ssh-identity
Skill0 starsChanged 3 months agoMITView on GitHub
Configures developer identity for git and GitHub on macOS - git config defaults, ed25519 SSH key in Apple Keychain, gh auth, SSH commit signing, includeIf work/personal identities, global gitignore. Use for "set up git", "SSH key for GitHub", "sign commits", "passphrase asked every time", "separate work and personal git email". Not for installing git/gh, branching workflows, or repo settings.
- Reads credentials
- Installs packages
In this repository21 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- add-skillSkill
- publish-repoSkill
- ai-dev-toolsSkill
- cloud-dev-setupSkill
- dev-cli-toolsSkill
- docker-on-macSkill
- dotfiles-setupSkill
- editor-setupSkill
- homebrew-setupSkill
- language-runtimesSkill
- mac-dev-appsSkill
- mac-maintenanceSkill
- macos-defaultsSkill
- macos-dev-setupSkill
- macos-security-baselineSkill
- macos-system-prepSkill
- mobile-dev-setupSkill
- web-dev-setupSkill
- zsh-setupSkill
The file
We split this skill into the rules it gives an agent
8 rules. About 0 are common, 4 are distinctive, and 4 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈4
Distinctive · estimate
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 23
Never overwrite an existing key: Check ls ~/.ssh/ first; creating over id_ed25519 destroys access.
- Distinctive: line 28
Ask for the user's real name/email — never invent or reuse placeholder identity values.
- Distinctive: line 61
Never truncate an existing file — append only missing entries:
- Very specific: line 80
If ssh -G shows a 1Password IdentityAgent or an existing github.com block pointing at another key, stop and merge deliberately (edit that …
- Very specific: line 108
Use Apple's /usr/bin/ssh-add — Homebrew/other OpenSSH builds don't have --apple-use-keychain.
- Very specific: line 120
No gh? pbcopy < ~/.ssh/id_ed25519.pub → GitHub → Settings → SSH and GPG keys → New SSH key (type: Authentication).
- Distinctive: line 153
Test: commit in a scratch repo, git verify-commit HEAD / git log --show-signature -1.
- Distinctive: line 169
Verify from inside each tree: git config user.email.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Git & SSH Identity
Sets up who-you-are for git: identity, keys, auth, signing, and the config
defaults core git developers actually use. Owns ~/.gitconfig (via
git config --global, inherently idempotent) and ~/.ssh/config's GitHub
block.
When NOT to use
- Git workflows (rebase, merge, commit messages) → native competence
- Installing git/gh binaries →
dev-cli-tools - Repo-side settings (branch protection, secrets) → not a machine-setup task
- Touch ID / FileVault →
macos-security-baseline
Safety rails
- Never overwrite an existing key. Check
ls ~/.ssh/first; creating overid_ed25519destroys access. New purpose → new filename. - Passphrases and tokens never appear in chat, files, or command args; auth
flows are browser-based (
gh auth login) or interactive (ssh-keygenprompts). - Ask for the user's real name/email — never invent or reuse placeholder identity values.
- Existing
user.email/user.namepresent? Show current values and confirm before changing.
Workflow
1. Identity + config defaults
git config --global user.name "<ask the user>"
git config --global user.email "<ask the user>"
git config --global init.defaultBranch main
git config --global fetch.prune true
git config --global rebase.autoStash true
git config --global push.autoSetupRemote true # git >= 2.37; kills --set-upstream dance
git config --global rerere.enabled true
git config --global merge.conflictstyle zdiff3 # git >= 2.35
git config --global diff.colorMoved plain
git config --global branch.sort -committerdate
git config --global column.ui auto
git config --global help.autocorrect prompt
# Editor: ASK which editor the user has, verify the command exists, then e.g.:
command -v code >/dev/null && git config --global core.editor "code --wait"
# Workflow choice, not universal - ask if the team merges on pull:
git config --global pull.rebase trueRationale per key: references/git-config.md.
2. Global gitignore
Never truncate an existing file — append only missing entries:
[ -f ~/.gitignore_global ] && cp ~/.gitignore_global ~/.gitignore_global.bak.$(date +%Y%m%d%H%M%S)
for e in .DS_Store '*.swp' .env node_modules/ __pycache__/ .venv/ .idea/ .vscode/; do
grep -qxF "$e" ~/.gitignore_global 2>/dev/null || echo "$e" >> ~/.gitignore_global
done
git config --global core.excludesfile ~/.gitignore_global3. SSH key + Apple Keychain
First inspect what already exists — both keys and effective config:
ls ~/.ssh/id_* 2>/dev/null # existing keys? pick ONE with the user
ssh -G github.com | grep -Ei '^(identityfile|identityagent)' # existing config/1Password agent?If ssh -G shows a 1Password IdentityAgent or an existing github.com
block pointing at another key, stop and merge deliberately (edit that
block with the user) — appending a second Host github.com block does not
override the first. 1Password users skip key generation entirely (its
agent + op-ssh-sign handle auth and signing; configure per its docs).
Otherwise, settle on ONE key path and use it consistently everywhere below (existing key → reuse; new: only into a free filename):
KEY=~/.ssh/id_ed25519 # the agreed path - substitute throughout
[ -f "$KEY" ] || ssh-keygen -t ed25519 -C "<email>" -f "$KEY" # SET A PASSPHRASEWire agent + Keychain so the passphrase is asked once ever
(~/.ssh/config; back the file up first if it exists):
Host github.com
AddKeysToAgent yes
UseKeychain yes
IdentityFile <the agreed KEY path>/usr/bin/ssh-add --apple-use-keychain "$KEY"Use Apple's /usr/bin/ssh-add — Homebrew/other OpenSSH builds don't have
--apple-use-keychain. After reboot the agent is empty but the config block
reloads the key transparently on first use.
4. GitHub auth
gh auth login # browser flow; SSH protocol; can create+upload the key for you
gh auth status
ssh -T git@github.com # expect: "Hi <user>! You've successfully authenticated..."No gh? pbcopy < ~/.ssh/id_ed25519.pub → GitHub → Settings → SSH and GPG
keys → New SSH key (type: Authentication). First ssh -T shows a host
fingerprint prompt — verify against GitHub's published fingerprints page
before typing yes.
5. SSH commit signing (opt-in — Verified badge)
An explicit choice, not a default: global commit.gpgsign makes every
commit fail if the key/agent is unavailable. Confirm the user wants it
(and check nothing is configured already: git config --global
--get-regexp '^(gpg|commit\.gpgsign|tag\.gpgsign)').
git config --global gpg.format ssh
git config --global user.signingkey "$KEY.pub" # the agreed key from step 3
git config --global commit.gpgsign true
git config --global tag.gpgsign trueUpload the same public key a second time on GitHub with type
Signing (gh ssh-key add "$KEY.pub" --type signing) — authentication
and signing entries are separate; skipping this leaves commits
"Unverified".
Local verification needs an allowed-signers file (idempotent; use the
identity email from step 1, not directory-dependent git config):
LINE="<email from step 1> $(cat "$KEY.pub")"
grep -qxF "$LINE" ~/.ssh/allowed_signers 2>/dev/null || echo "$LINE" >> ~/.ssh/allowed_signers
git config --global gpg.ssh.allowedSignersFile ~/.ssh/allowed_signersTest: commit in a scratch repo, git verify-commit HEAD / git log
--show-signature -1. Requires git ≥ 2.34 (SSH signing) — CLT git qualifies.
6. Work/personal identity split (when asked)
# ~/.gitconfig
[includeIf "gitdir:~/work/"]
path = ~/.gitconfig-work
[includeIf "gitdir:~/personal/"]
path = ~/.gitconfig-personalEach included file sets its own user.email (and optionally signingkey).
The trailing / matches the tree recursively. Remote-based alternative
(git ≥ 2.36): [includeIf "hasconfig:remote.*.url:git@github.com:acme/**"].
Verify from inside each tree: git config user.email.
7. Verify
sh "${CLAUDE_SKILL_DIR}/scripts/check.sh"Output spec
Done means: the managed keys read back correctly —
git config --global --show-origin --get-regexp \
'^(user\.(name|email|signingkey)|init\.defaultbranch|core\.(editor|excludesfile)|gpg\.|commit\.gpgsign|tag\.gpgsign)'(targeted query, not --list — a full dump can expose credential-bearing
URLs into the transcript) — ssh -T git@github.com prints the "Hi
<user>!" greeting (exit code 1 is the success case), a signed test
commit verifies locally (if signing was chosen), the passphrase survives
a new shell, and no existing key or config block was touched without
consent.
Gotchas
- "permission denied (publickey)" with a working key usually = key not
loaded (run the ssh-add line) or the repo remote uses HTTPS while auth
was set up for SSH (
git remote -vto check). - Signing on but key not uploaded as Signing type → GitHub shows Unverified; the auth entry does not count.
UseKeychainon a passphrase-less key errors on some setups — omit it then (but keys should have passphrases).- Two GitHub accounts (not just two emails) need more than includeIf:
per-account keys +
Host github-workaliases withIdentitiesOnly yesand matching remote URLs — say so instead of half-configuring it. gh auth login's token normally lands in the macOS keychain but can fall back to a plaintext~/.config/gh/hosts.yml— promise the browser flow (no pasted tokens), not a storage guarantee.- CLT git lags upstream slightly (updates only with Xcode releases). Fine
for everything here;
brew install gitif newer features are needed — brew's PATH position shadows it automatically.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

