swain-keys
swain-keys
Per-project SSH key provisioning for git signing and authentication.
When invoked
Locate and run the provisioning script at skills/swain-keys/scripts/swain-keys.sh:
SCRIPT="$(find . .claude .agents -path '*/swain-keys/scripts/swain-keys.sh' -print -quit 2>/dev/null)"
If the path search fails, glob for **/swain-keys/scripts/swain-keys.sh.
Workflows
Default (no arguments or "set up keys")
Run --status first to show current state:
bash "$SCRIPT" --status
If keys are not fully provisioned, ask the user if they'd like to proceed with provisioning.
Provision ("provision keys", "configure signing", "set up SSH")
Run the full provisioning flow:
bash "$SCRIPT" --provision
The script will:
- Derive a project name from the git remote or directory
- Generate
~/.ssh/<project>_signing(ed25519, no passphrase) if not exists - Create
~/.ssh/allowed_signers_<project>with the configured git email - Add the public key to GitHub via
gh ssh-key addfor both authentication and signing - Create
~/.ssh/config.d/<project>.confwith a host alias that bypasses global SSH agents - Update the git remote URL to use the project-specific host alias
- Set local git config for commit and tag signing
- Verify SSH connectivity and signing capability
Status ("key status", "check keys")
bash "$SCRIPT" --status
Verify ("verify keys", "test signing")
bash "$SCRIPT" --verify
Handling scope refresh
If gh ssh-key add fails due to insufficient scopes, the script will print an action-needed message. When this happens:
- Tell the user they need to authorize additional GitHub scopes
- Show them the command:
gh auth refresh -s admin:public_key,admin:ssh_signing_key - This will open a browser for OAuth — it requires human interaction
- After they confirm, re-run
--provision(idempotent, will skip completed steps)
Integration with swain-init
When called from swain-init, run --provision directly without the status-first flow. swain-init handles the "would you like to?" prompt.
Session bookmark
After provisioning, update the bookmark: bash "$(find . .claude .agents -path '*/swain-session/scripts/swain-bookmark.sh' -print -quit 2>/dev/null)" "Provisioned SSH keys for {project}"
Error handling
- If not in a git repo: fail with clear message
- If
ghCLI unavailable: skip GitHub registration steps, warn user to add keys manually - If git email not configured: fail early with instructions
- All steps are idempotent — safe to re-run after fixing issues