SSH config hardening now presents directives in logical groups
(matching the git config UX) with reasoning for each:
- Host Verification: TOFU rationale, known_hosts exfiltration risk
- Key & Agent Management: key enumeration attack, passphrase fatigue
- Algorithm Restrictions: downgrade attack, intentional RSA breakage
Each group batches its directives into a single prompt instead of
asking one-by-one.
Bump version to 0.3.1.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
FIDO2 hardware key generation now handles diverse security keys:
- Detect ed25519-sk vs ecdsa-sk support via ykman/fido2-token, with
automatic fallback chain: ed25519-sk → ecdsa-sk → ecdsa-sk -O resident
- Detect FIDO hardware by HID usage page (0xF1D0) instead of hardcoded
Yubico vendor ID — works with SoloKeys, Titan, Nitrokey, etc.
- Check libfido2 availability via ldconfig, dpkg-query, and rpm
- Warn on Qubes OS vhci_hcd USB passthrough (corrupts CTAP2 messages)
- Suppress admin recommendations when dependency is missing so install
instructions stay visible
- Accept ecdsa-sk keys in signing key filter
New --reset-signing flag clears git signing config, removes
allowed_signers entries, and moves/deletes key files so a fresh key
can be generated.
Bump version to 0.3.0.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Document what each setting does, what attack it mitigates, what
could break, and why we chose this default. Covers all git config
settings, SSH directives, and audit-only checks.
Co-Authored-By: Claude <noreply@anthropic.com>
IFS=$'\n\t' broke space-delimited read in summary and array join
in parallel status message. Use explicit IFS=' ' where needed.
Co-Authored-By: Claude <noreply@anthropic.com>
Arch Linux doesn't publish ARM64 container images. Auto-skip with
SKIP status on non-x86_64 architectures.
Co-Authored-By: Claude <noreply@anthropic.com>
Build images sequentially (shared layer cache), then run BATS and
interactive tests across all distros in parallel. Output captured
to temp files, failures show log tail. Significantly faster for
multi-distro runs.
Co-Authored-By: Claude <noreply@anthropic.com>
Document all three test tiers (BATS, interactive, e2e containers)
with usage examples, flags, and requirements.
Co-Authored-By: Claude <noreply@anthropic.com>
Only export GIT_CONFIG_GLOBAL in tmux sessions when already set.
An empty value tells git "no global config" vs unset (uses ~/.gitconfig).
Also fix stat format detection in SSH permissions test.
Co-Authored-By: Claude <noreply@anthropic.com>
Use if/else for stat format detection instead of || which can fail
under set -e. Remove run wrapper for apply_ssh_config.
Co-Authored-By: Claude <noreply@anthropic.com>
Detect Homebrew openssh by checking for ssh-sk-helper binary instead
of running ssh-keygen (which blocks waiting for a FIDO touch).
Co-Authored-By: Claude <noreply@anthropic.com>
Use Homebrew ssh-keygen for FIDO2 key generation on macOS instead of
searching for libsk-libfido2.dylib (removed in modern openssh). Group
interactive apply prompts into 6 categories with explanations. Fix
Linux gitleaks install hint to show apt/dnf instead of brew.
Co-Authored-By: Claude <noreply@anthropic.com>
Replace ~25 individual y/n prompts with 6 logical groups, each showing
a table of pending changes with one-line explanations before prompting.
Also fix FIDO2 middleware detection (needs brew openssh, not just libfido2).
Co-Authored-By: Claude <noreply@anthropic.com>
Add test/run-interactive.sh that runs tmux interactive tests on
the host in an isolated HOME. Covers macOS ssh-keygen which
cannot be tested in Linux containers. e2e.sh now runs host
interactive tests first, then container matrix. Skips gracefully
if tmux is not installed.
Closes: #23🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
e2e.sh now runs both BATS and interactive tests per distro:
build -> BATS -> interactive. Failure stage shown in summary.
Closes: #22🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add security items from post-bump hygiene fixes to the 0.1.0
changelog entry.
Closes: #16🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Remove unused SIGNING_KEY_PATH variable (dead code), add trap for
temp file cleanup in apply_ssh_directive, add -- separator before
ssh-keygen path arguments, add info message when falling back to
in-memory credential cache on Linux.
Closes: #15🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Warn users in the signing wizard that reusing the same signing key
across personal and work accounts enables cross-platform identity
correlation. Recommend separate keys per org with git includeIf.
Also added to admin recommendations section.
Closes: #12🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Change prompt default from Y to N so users must explicitly opt in.
Fix gemini command to use -p flag for non-interactive stdin mode.
Consolidate review prompt text into a variable.
Closes: #11🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add safety gate prompt to all interactive tmux scenarios, add new
"safety gate decline" test scenario, update acceptance criteria.
Closes: #10🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Use 10#$var arithmetic prefix to avoid bash interpreting leading
zeros as octal (e.g., 08 or 09 would cause "value too great for
base" errors). 2 new tests (64 total).
Closes: #9🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replace sed 's/[^0-9.]//g' with grep -oE for semver extraction —
fixes breakage on Apple Git suffix and rc versions. Add
strip_ssh_value() helper to strip inline comments and surrounding
quotes from SSH config values. Applied to IdentityFile scanning,
audit_ssh_directive, and apply_ssh_directive. 9 new tests (62 total).
Closes: #8🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Asks users to confirm they've reviewed the script before it modifies
config. On decline, prints instructions for piping the script to
Claude Code or Gemini CLI for a security review. Skipped with -y
and --audit flags. 3 new tests (53 total).
Closes: #7🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Covers arg parsing, version comparison, audit phase (git config,
signing, SSH), apply phase (settings, SSH directives, url rewrite),
signing key detection (standard/custom/tilde/sk-preference),
allowed signers, -y mode, backup, and end-to-end idempotency.
All tests run in isolated HOME to avoid touching real config.
Closes: #6🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fix incorrect CVE reference for core.fsmonitor, clarify bash/zsh
compatibility (shebang is bash, works from zsh sessions), fix -y mode
signing behavior to not break commits when no key exists, clarify
submodule.recurse scope, add pull.rebase conflict warning, improve
SSH config and credential helper detection specifics, add FIDO2
touch prompt, and clarify audit exit code for missing signing keys.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Interactive shell script that audits and hardens global git config
with security-focused defaults: object integrity, protocol restrictions,
filesystem protection, hook control, SSH signing with FIDO2 support,
and credential security.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>