swain-keys
Per-project SSH key provisioning for git signing and authentication.
When invoked
Locate and run the provisioning script at scripts/swain-keys.sh (relative to this skill's directory):
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
SCRIPT="$REPO_ROOT/.agents/bin/swain-keys.sh"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" --statusIf 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" --provisionThe 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 and routes GitHub SSH overssh.github.com:443 - 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" --statusVerify ("verify keys", "test signing")
bash "$SCRIPT" --verifyHandling 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 "$REPO_ROOT/.agents/bin/swain-bookmark.sh" "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