Note: the entire codebase in this repository was generated by an AI coding assistant based on my requirements. Bug reports and PRs are still very welcome — see Contributing.
sshkit is a single CLI that handles SSH key generation, ~/.ssh/config
edits, ssh-agent loading, connection tests, and per-repo
user.name / user.email setup.
It's a small hobby tool. I describe the requirements; an AI writes the code. Clone it, build it, poke at it — and feel free to send a PR if you make it nicer.
You need these on your PATH before sshkit is useful:
- OpenSSH client —
ssh,ssh-keygen,ssh-add,ssh-agent. Dropbear / libssh are not supported. - git — used to set per-repo identity.
Supported platforms: macOS and Linux. Windows is not supported on purpose.
No package manager, no Homebrew tap, no release binary. Just clone and build:
git clone https://github.com/gitdust/sshkit.git
cd sshkit
# you need Go installed (1.22+ recommended)
go version
make build # produces ./bin/sshkit
./bin/sshkit --helpIf you want the binary on your PATH:
make install # drops it into ~/.local/bin/sshkitOr just go install:
go install ./cmd/sshkitThat's it. The binary is self-contained — no config files, no daemons, no background services.
Three common scenarios:
One key per account, different Host aliases in ~/.ssh/config:
sshkit gen account1 # hostname: github.com, user: git, alias: github-account1
sshkit gen account2 # hostname: github.com, user: git, alias: github-account2Clone through the alias to pick which account to use:
git clone git@github-account1:owner/repo.git
git clone git@github-account2:owner/repo.gitEach target remembers the name and email you gave during sshkit gen. Inside any cloned repo, just run sshkit config (no arguments) —
it reads the origin remote URL, finds the matching target by alias
(e.g. github-account1), and writes that target's name / email
into the repo's local git config. No more committing as the wrong
account by accident.
cd owner/repo
sshkit config # picks up github-account1 → sets user.name + user.emailRun it once per repo, right after cloning. If the remote URL uses the
real hostname (e.g. git@github.com:owner/repo.git) instead of the
alias, sshkit config will still find the target by hostname but
print a warning suggesting you switch the URL to the alias — that way
pushes go through the right key.
One key per host:
sshkit gen gitee # hostname: gitee.com
sshkit gen gitlab # hostname: gitlab.company.comUse your server login name (root / ubuntu / ...) as the user;
sshkit will skip the commit-identity questions:
sshkit gen vps
# hostname: 203.0.113.10
# user: root
# port: 22sshkit gen only creates the keypair locally — the VPS still has no
idea who you are. Push the public key to the server's
authorized_keys (one line if the VPS still accepts password login):
ssh-copy-id vpsIf the VPS is already key-only, or you'd rather do it by hand, the
wizard will print the exact public-key path and a ready-to-paste
command on failure. After that, ssh vps just works.
sshkit doctor # environment check (--fix to auto-repair; includes agent reachability)
sshkit gen [name] # interactive wizard: generate key + write target
sshkit list # list all keys and targets
sshkit test [alias] # test connection (auto-detects host when run inside a git repo)
sshkit config [alias] # set user.name / user.email in the current repo
sshkit remove --host <alias> [--purge] # remove a target by SSH alias (deletes the whole entry when it's the last one)Global flags: --yes (skip confirmations, used by config / remove),
--dry-run (print the plan only), --version.
If something goes wrong mid-gen — or you hit Ctrl+C — sshkit
rolls back the partial changes, so it's safe to re-run.
sshkit test --json # single JSON object on stdout, for scripts
sshkit config --yes # skip confirmation, write current repo
sshkit remove --host <alias> --yes # skip confirmation, delete
sshkit remove --host <alias> --purge # also unload from agent + delete key filegen is an interactive wizard and intentionally has no non-interactive
mode.
sshkit does not ship its own agent start / agent status subcommands
— ssh-agent is already a one-liner, and wrapping it adds no value.
Agent reachability is folded into sshkit doctor (look for the
ssh-agent reachable line). To start an agent manually:
eval $(ssh-agent) # any subcommand that needs the agent will remind youPRs are very welcome. This is a small project, so:
- Open an issue first if your change is non-trivial (new flag, new subcommand, behavior change). It saves everyone a round-trip.
- Keep the scope tight. One PR = one thing.
- Add a test if you change behavior in
internal/...orcmd/sshkit/cmd/....make testruns the full suite with-race. - Don't worry about being perfect. I review fast and I'd rather merge a 90% PR than block on polish.
Local dev loop:
make build && ./bin/sshkit doctor # quick smoke test
make test # go test -race ./...
make vet # go vet ./...
make snapshot # build a local goreleaser snapshotBug reports and ideas are also welcome — just open an issue.
MIT — do whatever you want, just keep the copyright notice.