You're reading the Keybase blog.
There are more posts.

August 22, 2019

Better SSH Authentication with Keybase

The most common way of handling SSH authentication is public key authentication. This is much stronger than simply using a password, but it creates the problem of how to securely manage changes to SSH keys over time. If ten new people join a company and five others leave, someone has to add the ten new keys to each server and remove the previous five. This is a process ripe for automation. Some companies do it by centralizing storage of SSH public keys and baking them into images as applications are deployed. But SSH supports another way of handling authentication: Certificate Authorities (CAs).

With an SSH CA model, you start by generating a single SSH key called the CA key. The public key is placed on each server and the server is configured to trust any key signed by the CA key. This CA key is then used to sign user keys with an expiration window. This means that signed user keys can only be used for a finite, preferably short, period of time before a new signature is needed. This transforms the key management problem into a user management problem: How do we ensure that only certain people are able to provision new signed SSH keys?

Keybase SSH CA

Enter Keybase. Keybase Teams allow us to easily define secure auditable groups of Keybase users. And each Keybase user is defined by a strong cryptographic identity. Keybase Chat provides end to end encrypted and authenticated messaging on top of Keybase Teams. This is a powerful primitive that can be used for building secure, encrypted workflows. We recently open-sourced chatbot libraries for Go, Python, and TypeScript that make all of this a lot more accessible. We’ve developed and open-sourced a chatbot for managing SSH keys on top of Keybase.

Demo of using kssh

With our SSH CA chatbot, you can define subteams for managing access to different resources. For example, internally we have two that we use to control SSH access, keybase.ssh.production and keybase.ssh.staging.

Granting a new employee access is as easy as adding them to the relevant Keybase team. And even better, revoking access is just a matter of removing someone from a team. All of this is backed by Keybase's identity system and built on top of Keybase as a chatbot. There are two components to this system.

  • keybaseca is the server side of the chatbot that receives signature requests via Keybase chat. keybaseca will only sign an SSH key if it comes from someone in the configured teams. It also keeps detailed audit logs on signed keys including information about what device provisioned a given key.
  • kssh is a wrapper around ssh, and is the client side of the chatbot, sending signature requests via Keybase chat. As a user of the CA bot, you don't have to think about creating new keys, key expiration, or identity. You just run kssh user@server instead of ssh user@server and keys are automatically provisioned in the background.

This removes the need to manage SSH keys manually, and we think it increases security for most teams. See the Getting Started directions on Github for information about setting up and deploying the Keybase SSH CA bot. It's easy to get up and running, so there's no reason not to give it a try. I even use it for managing SSH access to my personal servers!

Keybase ChatOps

We’re really excited about the potential for ChatOps flows built on top of Keybase, so we’d love to see what else people create! A few ideas we’ve thought of: password management, TOTP sharing, AWS IAM credential sharing, and CI/CD integrations.

— David Dworken


Is this secure?

We think so! It is a small codebase written in Go that we have carefully audited internally. We also have extensive integration tests. But if you find anything, please let us know.

What happens if Keybase goes down?

The keybaseca command supports exporting the CA key as a normal SSH private key. This ensures that even if Keybase goes down, you can use that key to manually sign user keys. Additionally, already provisioned keys will continue to be valid until they expire.

What about scp, rsync, etc?

While we don’t ship a kscp or a krsync, the kssh command can be used to provision a new SSH key and add it to the ssh agent. Run it like this: kssh --provision && scp ...

How do you audit SSH connections if everyone uses the same user?

The chatbot has built in audit logs that log detailed information about provisioned SSH keys. An audit log contains the Keybase user, the name of the device used to make the request, the ID of their SSH key, and the expiration window of their SSH key. We suggest storing these logs to a private (encrypted, access-controlled, durable, and signed) KBFS directory. Here's an example audit log entry:

[2019-07-29 13:53:24.260524144 -0400 EDT m=+409.501374229] Processing SignatureRequest from user=dworken on device='work-laptop-5' keyID:9d1bf1d9-56c3-4cd2-a377-4a4afc885a9e:217c6ad7-fe80-47d1-ba9d-e3d7bcccbf3e, principals:prod, expiration:+2h, pubkey:ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAvDOsE5X/+2TixRzUwvfKhLydjYE98zsnKGG2tbaL+b david@laptop

In addition, since this is a chatbot you automatically get notifications every time someone uses SSH:

Demo of using kssh

Does this give Keybase access to my servers?

Nope! Thanks to our work on using sigchains to verify team membership, there is no way that we could inject a user into your teams. And without doing that, there is no way that running this bot gives us access to your servers.

Other Questions, feedback, or suggestions?

Reach out to @dworken on Keybase!

This is a post on the Keybase blog.