{"id":15675017,"url":"https://github.com/42wim/ssh-agentx","last_synced_at":"2026-03-05T00:03:38.575Z","repository":{"id":57707873,"uuid":"361020173","full_name":"42wim/ssh-agentx","owner":"42wim","description":"Extended ssh-agent which supports git commit signing and yubikey signing over ssh","archived":false,"fork":false,"pushed_at":"2024-04-29T22:20:11.000Z","size":3379,"stargazers_count":18,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-06T21:05:24.006Z","etag":null,"topics":["codesigning","git","gpg","relic","signing-commits","ssh-agent","yubikey"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/42wim.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-04-23T22:31:10.000Z","updated_at":"2025-02-07T15:54:43.000Z","dependencies_parsed_at":"2024-06-19T04:00:41.549Z","dependency_job_id":"5530ad08-6efe-4da4-8654-a2016bfb238c","html_url":"https://github.com/42wim/ssh-agentx","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/42wim/ssh-agentx","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/42wim%2Fssh-agentx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/42wim%2Fssh-agentx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/42wim%2Fssh-agentx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/42wim%2Fssh-agentx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/42wim","download_url":"https://codeload.github.com/42wim/ssh-agentx/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/42wim%2Fssh-agentx/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30101697,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-04T23:59:36.199Z","status":"ssl_error","status_checked_at":"2026-03-04T23:56:48.556Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["codesigning","git","gpg","relic","signing-commits","ssh-agent","yubikey"],"created_at":"2024-10-03T15:54:53.655Z","updated_at":"2026-03-05T00:03:38.532Z","avatar_url":"https://github.com/42wim.png","language":"Go","readme":"# ssh-agentx\n\n\u003c!-- TOC --\u003e\n\n- [ssh-agentx](#ssh-agentx)\n  - [Rationale](#rationale)\n  - [Requirements gpg signing](#requirements-gpg-signing)\n  - [Requirements yubikey signing](#requirements-yubikey-signing)\n  - [Configuration ssh-agentx gpg](#configuration-ssh-agentx-gpg)\n  - [Configuration ssh-agentx yubikey](#configuration-ssh-agentx-yubikey)\n  - [Configuration ssh-gpg-signer](#configuration-ssh-gpg-signer)\n    - [Linux](#linux)\n    - [Windows](#windows)\n  - [Configuration relic yubikey](#configuration-relic-yubikey)\n  - [Signing commits after configuration](#signing-commits-after-configuration)\n\n\u003c!-- /TOC --\u003e\n\nThe x stands for eXtended or Xtra.\n\nssh-agentx is a ssh-agent replacement that abuses the SSH Extension protocol to sign git commits using your existing ssh keys (that you import into this agent).\n\nWhen running under windows it also supports WSL/Pageant/WSL2/Cygwin thanks to the great \u003chttps://github.com/buptczq/WinCryptSSHAgent\u003e tool.\n\nIt also now supports yubikey signing combined with relic on my fork - \u003chttps://github.com/42wim/relic/tree/sshtoken\u003e\n\n## Rationale\n\nBecause the one thing I need PGP for is to sign git commits AND I'm working mostly on (shared) remote servers.  \nI don't want to setup a pgp/gpg configuration, keep a private key on the shared server and maintain it.  \nAs there is already remotely running a ssh-agent containing ed25519/rsa keys that can be used to do the same thing over the `SSH_AUTH_SOCK` socket.\n\nThe rationale above is gone now we can use ssh keys to sign git commits.\n\nBut this agent is being reused for code signing with yubikey over ssh, as code signing certificates now requires hardware tokens.  \nIn this setup you have a laptop with the yubikey and a remote server containing your builds.  \n\nThis setup is tested with a yubikey 5C\n\n## Requirements gpg signing\n\nIf you only want to sign commits and never need to do `git log --show-signature` or `git verify-commit` you don't need gpg on the server.\n\nYou do need my companion tool that git will talk to when signing commits. See \u003chttps://github.com/42wim/ssh-gpg-signer\u003e\n\n## Requirements yubikey signing \n\nThis tool works together with my fork of relic on \u003chttps://github.com/42wim/relic/tree/sshtoken\u003e  \nGo build this tool and see the section about relic configuration below.\n\nYou'll need to build this and make a relic.yml configuration file, you can find an example below:  \n\n```yaml\n---\ntokens:\n  ssh9a:\n    type: ssh\n    slot: \"9a\"\nkeys:\n  ssh9a:\n    token: ssh9a\n    x509certificate: yourcertificate.crt\n    slot: \"9a\"\n```\n\nAfter this you can use relic to sign an executable with\n\n`relic sign -k ssh9a -f yourfile.exe -o yourfile-signed.exe`\n\nSo the setup is that on your laptop you're running ssh-agentx, you ssh into the server and there you run the relic command that will sign your executable using SSH extensions to talk to ssh-agentx which will talk to your yubikey plugged into your laptop.\n\n## Configuration ssh-agentx gpg\n\nIf you want to run this agent instead of ssh-agent without the gpg signing stuff, you don't need a configuration.\n\nOtherwise create a file called `ssh-agentx.toml` you can put in the same directory as `ssh-agentx` when testing or put it in `~/.config/ssh-agentx/ssh-agentx.toml` or `%APPDATA%\\ssh-agentx\\ssh-agentx.toml` on windows.\n\nThis file must contain a `[gpg.something]` header in case you have different git identities (you can use the same key for different identities if you want)\n\nThe `name` and `email` must match the email of your git configuration and the `matchcomment` must match the comment of your sshkey. (you can change comments of your keys using `ssh-keygen -c -f ~/.ssh/yourkey`).\n\nYou can also find the comment of your keys when running `ssh-add -l`\n\n(:warning: It's better to create a new key to use solely for the gpg signing, read up on \u003chttps://security.stackexchange.com/questions/1806/why-should-one-not-use-the-same-asymmetric-key-for-encryption-as-they-do-for-sig\u003e for why, you can still use an existing one if you want though)\n\n```toml\n[gpg.github]\nname=\"yourname\" #this must match your .gitconfig name\nemail=\"youremail\" #this must match your .gitconfig email\nmatchcomment=\"akeycomment\" #this must match a ssh key comment\n```\n\nSo save this config above, start `ssh-agentx` and set your `SSH_AUTH_SOCK` path correct.\n\nWhen you now add your key(s) to the agent `ssh-add ~/.ssh/ed25519` and it matches the `matchcomment` as above it'll give you a PGP public key block as shown below.\n\n```text\n2021/04/24 17:49:43 adding public key for yourname \u003cyouremail\u003e\n-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nxjMEAAAAABYJKwYBBAHaRw8BAQdAdN2uijeJajk1p9tJ+zaGR4ZtmxrrijPzJ195\n1NKx8DDNFHlvdXJuYW1lIDx5b3VyZW1haWw+wogEExYIADoFAgAAAAAJEBTLefcM\n08E9FiEERSpAhAOO4sCnMMBpFMt59wzTwT0CGwMCHgECGQEDCwkHAhUIAiIBAABf\nAgEAuoHPX5vGBG95czyjHBxlfa3WKBEZKO5Oq9QYzy6Hq94A/02qShQlAkQs2Plz\nIaub4hgLmJWE1jk62pdjGP/VsIwA\n=KL1J\n-----END PGP PUBLIC KEY BLOCK-----\n```\n\nYou can now copy this in your github or gitea GPG settings.\n\nThis concludes the agent side configuration, you also need the companion which will interact with git to sign it and send it to ssh-agentx.\n\n## Configuration ssh-agentx yubikey\n\nIf you want to run this agent instead of ssh-agent without the yubikey signing stuff, you don't need a configuration.\n\nOtherwise create a file called `ssh-agentx.toml` you can put in the same directory as `ssh-agentx` when testing or put it in `~/.config/ssh-agentx/ssh-agentx.toml` or `%APPDATA%\\ssh-agentx\\ssh-agentx.toml` on windows.\n\nThe `enable=true` is needed to actually use the yubikey signing part of ssh-agentx\n\n```toml\n[yubikey]\nenable=true #needed to enable yubikey signing\nenablelog=true #enable logging about yubikey operations\ndefaultslot=\"9a\" #define the default yubikey slot to use (9a is the default authentication one)\n```\n\nBelow is an example of the logs when signing\n```\n2024/04/29 23:19:24 got ssh-yubi-setslot@42wim setting slot to 9a\n2024/04/29 23:19:24 got ssh-yubi-setslot@42wim new crypto signers set\n2024/04/29 23:19:24 got ssh-yubi-publickey@42wim request for publickey\n2024/04/29 23:19:24 got ssh-yubi-setslot@42wim setting slot to 9a but already set.\n2024/04/29 23:19:24 got ssh-yubi-publickey@42wim request for publickey\n2024/04/29 23:19:24 got ssh-yubi-setslot@42wim setting slot to 9a but already set.\n2024/04/29 23:19:24 got ssh-yubi-sign@42wim request to sign\n```\n\n## Configuration ssh-gpg-signer\n\n### Linux\n\nDownload/build \u003chttps://github.com/42wim/ssh-gpg-signer\u003e and put the binary somewhere, lets assume `/home/user/bin/ssh-gpg-signer`.\n\nNow change your global or local gitconfig to use ssh-gpg-signer and always sign git commits\n\n```bash\ngit config --global gpg.program /home/user/bin/ssh-gpg-signer\ngit config --global commit.gpgSign true\n```\n\n### Windows\n\nDownload/build \u003chttps://github.com/42wim/ssh-gpg-signer\u003e and put the binary somewhere, lets assume `c:\\users\\user\\bin\\ssh-gpg-signer`.\n\nNow change your global or local gitconfig to use ssh-gpg-signer and always sign git commits\n\n```bash\ngit config --global gpg.program c:\\\\users\\\\user\\\\bin\\\\ssh-gpg-signer\ngit config --global commit.gpgSign true\n```\n\n## Configuration relic yubikey\n\nThis tool works together with my fork of relic on \u003chttps://github.com/42wim/relic/tree/sshtoken\u003e  \nYou'll need to build this and make a relic.yml configuration file, you can find an example below:  \n\n```yaml\n---\ntokens:\n  ssh9a:\n    type: ssh\n    slot: \"9a\"\nkeys:\n  ssh9a:\n    token: ssh9a\n    x509certificate: yourcertificate.crt\n    slot: \"9a\"\n```\n\nAfter this you can use relic to sign an executable with\n\n`relic sign -k ssh9a -f yourfile.exe -o yourfile-signed.exe`\n\nRunning relic for the first time will get you a PIN code popup to access your yubikey for signing.   \nWarning: Follow-up signing requests will use the cached pin (and won't need any interaction), so if you didn't specify a touch policy for your yubikey be sure to exit your SSH session, stop/kill ssh-agentx or just remove your yubikey when done signing.\n\nFor clarification: the setup is that on your laptop you're running ssh-agentx, you ssh into the server and there you run the relic command that will sign your executable using SSH extensions to talk to ssh-agentx which will talk to your yubikey plugged into your laptop.\n\n## Signing commits after configuration\n\nNow git will automatically sign your commits using `ssh-gpg-signer` which talks over the `SSH_AUTH_SOCK` socket to the `ssh-agentx`.\n\nSo just run `git commit -m \"acommit\"`\n\nIf you have `gpg` installed and you run `git log --show-signature` it'll show you something like this:\n\n```git\ncommit 73e3d4e2a897c921f207f5a1ae65c7b6175b1afe (HEAD -\u003e master)\ngpg: Signature made Sat 24 Apr 2021 05:18:00 PM CEST\ngpg:                using EDDSA key 452A4084038EE2C0A730C06914CB79F70CD3C13D\ngpg: Good signature from \"yourname \u003cyouremail\u003e\" [uncertain]\ngpg: WARNING: This key is not certified with a trusted signature!\ngpg:          There is no indication that the signature belongs to the owner.\nPrimary key fingerprint: 452A 4084 038E E2C0 A730  C069 14CB 79F7 0CD3 C13D\nAuthor:     yourname \u003cyouremail\u003e\nAuthorDate: Fri Apr 23 22:26:45 2021 +0200\nCommit:     yourname \u003cyouremail\u003e\nCommitDate: Fri Apr 23 22:26:45 2021 +0200\n\n    acommit\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F42wim%2Fssh-agentx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F42wim%2Fssh-agentx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F42wim%2Fssh-agentx/lists"}