yuvipanda / jupyterhub-ssh

SSH Access to JupyterHubs
BSD 3-Clause "New" or "Revised" License
94 stars 29 forks source link

Adding ability to associate ssh keys with usernames #25

Open costrouc opened 3 years ago

costrouc commented 3 years ago

@yuvipanda such a fan of the minimal(no) permissions that jupyterhub-ssh requires to launch terminals on behalf of users with their jupyterhub api key. We've added jupyterhub-ssh to qhub-onprem https://github.com/Quansight/qhub-onprem/blob/master/tasks/jupyterhub-ssh.yaml.

One issue we've seen with several clients is how they don't feel comfortable using password based auth and would prefer ssh keys. That said I know that the password the user supplies is used to launch the jupyter server on behalf of the user allowing jupyterhub-ssh to not have a sensitive admin api key. Do you have any design ideas on how to support this? We would be developing this feature. We would need to associate N ssh public keys with a given username and it would likely require the jupyterhub-ssh server to have an admin api key.

My idea on implementation. Often times I find that I need to associate metadata (often times not secrets) with a given user in this case public keys. I know that jupyterhub has auth-state but external api's do not have access to this data. If the hub had data about a user that could be queried over an api jupyterhub-ssh would have an easy way to gather associated ssh-keys for a user. This may be a feature that is waiting on rbac permissioning in jupyterhub to be completed https://github.com/jupyterhub/jupyterhub/tree/rbac.

yuvipanda commented 3 years ago

Great to see you, @costrouc.

In JupyterHub, admin services can actually access auth_state! So one way to do this is to get ssh public keys into auth_state on login, and have jupyterhub-ssh use that.

However, this sucks! jupyterhub-ssh currently has no privs required, which is great. I understand the need for this though.

The way to approach this is:

  1. Implement a generic 'Authenticator' interface. These can take SSH keys or passwords, and they have to return a token for the user in JupyterHub.
  2. Move the current user token based authenticator to this implementation
  3. Implement using ssh keys from JupyterHub auth_state as second authenticator
  4. Figure out how to keep generic non-encrypted state that's globaly accessible in JupyterHub. I'd love for 'profile' state that can contain many non-secret things, and is ideally editable by user. This might already be possible, though. Need to check.

Whatever we do here should match jupyterhub-sftp too. For ssh keys, that might mean some more work - probably involving AuthorizedKeysCommand. Should be doable though.

Happy to offer code review. Very excited to have you and others from quansight involved here :)

manics commented 3 years ago

https://github.com/jupyterhub/jupyterhub/issues/3189 might be relevant?