A couple of weeks ago I was working on adding SSH Certificate Authentication support to Wish, and did not find any good, to the point documentation on how to use certificates from the Go SSH client — hence this post.

In short, we need to parse the user’s private key and the certificate, create a signer using both the certificate and the private key, and use that as an auth method in our client.

Here’s a example:

// parse the user's private key:
pvtKeyBts, err := os.ReadFile("~/.ssh/id_ed25519")
if err != nil { /* handle it */ }

signer, err := ssh.ParsePrivateKey(pvtKeyBts)
if err != nil { /* handle it */ }


// parse the user's certificate:
certBts, err := os.ReadFile("/tmp/cert.pub")
if err != nil { /* handle it */ }

cert, _, _, _, err := ssh.ParseAuthorizedKey(certBts)
if err != nil { /* handle it */ }


// create a signer using both the certificate and the private key:
certSigner, err := ssh.NewCertSigner(cert.(*ssh.Certificate), signer)
if err != nil { /* handle it */ }


// use that signer as an auth method in our client config:
client, err := gossh.Dial("tcp", "foo.bar:22", &ssh.ClientConfig{
	User: "foo",
	Auth: []ssh.AuthMethod{
		ssh.PublicKeys(signer),
	},
})
if err != nil { /* handle it */ }


// proceed as usual
session, err := client.NewSession()
if err != nil { /* handle it */ }

// ...

As you can see, once you know what to do, it is quite simple.

Docs are a bit lacking, and my google-fu did not find any good results on this, so I wanted to put it out there for fellow developers trying to do the same.