Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.0.0
1.0.1
7 changes: 0 additions & 7 deletions dotfiles/ssh-config
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,8 @@

Host *
AddKeysToAgent yes
# 1Password SSH Agent (Secretive)
IdentityAgent "~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock"
ServerAliveInterval 60
ServerAliveCountMax 3

Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/developer_ed25519

# Per-project/client overrides
Include ~/.ssh/config.d/*.conf
54 changes: 48 additions & 6 deletions modules/07-ssh.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
# Module 07: SSH — fix permissions, generate config from discovered keys
# Module 07: SSH — fix permissions, discover keys, generate GitHub host config

source "$(dirname "$0")/../lib/core.sh"
source "$(dirname "$0")/../lib/state.sh"
Expand All @@ -8,27 +8,69 @@ SSH_DIR="${HOME}/.ssh"
mkdir -p "$SSH_DIR"
chmod 700 "$SSH_DIR"

# Fix permissions on all private keys
# Fix permissions on all private keys and collect key paths
KEY_COUNT=0
GITHUB_KEY=""
for key in "$SSH_DIR"/*; do
[ -f "$key" ] || continue
# Skip public keys and known_hosts
[[ "$key" == *.pub ]] && continue
[[ "$(basename "$key")" == "known_hosts"* ]] && continue
[[ "$(basename "$key")" == "authorized_keys" ]] && continue
[[ "$(basename "$key")" == "config"* ]] && continue
[[ "$(basename "$key")" == "environment" ]] && continue

chmod 600 "$key"
KEY_COUNT=$((KEY_COUNT + 1))
mbp_log_step "permissions 600: $(basename "$key")"

# Pick the best key for GitHub (prefer ed25519, then rsa)
local_name="$(basename "$key")"
if [ -z "$GITHUB_KEY" ]; then
GITHUB_KEY="$key"
fi
# Prefer developer_ed25519 (mbp convention) > id_ed25519 > any ed25519 > first key
case "$local_name" in
developer_ed25519) GITHUB_KEY="$key" ;;
id_ed25519) [[ "$(basename "$GITHUB_KEY")" != "developer_ed25519" ]] && GITHUB_KEY="$key" ;;
*ed25519*) [[ "$(basename "$GITHUB_KEY")" != "developer_ed25519" && "$(basename "$GITHUB_KEY")" != "id_ed25519" ]] && GITHUB_KEY="$key" ;;
esac
done

# Ensure config.d directory for per-client/per-project includes
mkdir -p "${SSH_DIR}/config.d"

# Create ~/.ssh/config if not already symlinked by dotfiles module
if [ ! -f "${SSH_DIR}/config" ] && [ ! -L "${SSH_DIR}/config" ]; then
mbp_log_step "No ~/.ssh/config found — dotfiles module will symlink it"
# Generate GitHub host config from discovered keys
GITHUB_CONF="${SSH_DIR}/config.d/github.conf"
if [ -n "$GITHUB_KEY" ]; then
cat > "$GITHUB_CONF" << EOF
# Generated by mbp — edit freely or delete to manage manually
Host github.com
HostName github.com
User git
IdentityFile ${GITHUB_KEY}
EOF
mbp_log_ok "GitHub SSH: using $(basename "$GITHUB_KEY")"
elif [ ! -f "$GITHUB_CONF" ]; then
mbp_log_warn "No SSH keys found — GitHub access requires a key in ~/.ssh/"
mbp_log_warn "Generate one: ssh-keygen -t ed25519 -C \"your@email\" -f ~/.ssh/id_ed25519"
fi

# Configure 1Password SSH agent only if it's installed
OP_AGENT_SOCK="${HOME}/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock"
OP_CONF="${SSH_DIR}/config.d/1password.conf"
if [ -S "$OP_AGENT_SOCK" ]; then
if [ ! -f "$OP_CONF" ]; then
cat > "$OP_CONF" << EOF
# Generated by mbp — 1Password SSH Agent
# Remove this file if you don't use 1Password for SSH keys
Host *
IdentityAgent "~/Library/Group Containers/2BUA8C4S2C.com.1password/t/agent.sock"
EOF
mbp_log_ok "1Password SSH agent detected and configured"
fi
elif [ -f "$OP_CONF" ]; then
rm "$OP_CONF"
mbp_log_step "1Password agent not found — removed stale config"
fi

mbp_log_ok "SSH: $KEY_COUNT keys secured"
Expand Down
Loading