How can you do dynamic, key-based SSH similar to GitHub?

Take a look at the command-option for SSH's authorized_keys-file. This way, you can force a command on specific users accessing your machine depending on their SSH key.

Imagine a user named "git" on your server. This user has the following authorized_keys-file as an example:

command="/path/to/script user1",no-port-forwarding,no-X11-forwarding,no-pty ssh-rsa [public key of user1]
command="/path/to/script user2",no-port-forwarding,no-X11-forwarding,no-pty ssh-rsa [public key of user2]

So when user1 runs ssh [email protected] "/execute/command --with --parameter", /path/to/script is called (as git user). This script can access the original command (/execute/command --with --parameter) in the environment variable $SSH_ORIGINAL_COMMAND (dive into the SSH documentation for more details).

This way, it is only a matter of getting the right lines into the authorized_keys-file (you could dynamically build the file from the keys stored in your database).

From there you could write your own shell or do whatever you want with the original command.

This is basically how gitolite and gitosis manage git repository permissions (Github uses one of these I think).

Hope this helps a bit - kind regards!


The OP specifically says that he want to assign keys to multiple users, and that he wants the users to be stored in a database, not as actual linux users. In the Github style setup mentioned above, there is a single git user.

For the answer to be complete, the OP would also need to use the AuthorizedKeyCommand directive, which is explained very well here - OpenSSH with public keys from database

So, you use a combination of both. Authentication to the server for x number of users, stored in a database, is done by . based on a custom authentication script (a bash script that you call some script in your web application from)

When your custom script is returning a public key to OpenSSH for authentication (in place of an authorized_keys file), you provide it in the format described in Michael Trojanek's answer. This way, you provide Authorization over specific functionality that your dynamic user can access.