Package: gh-scoped-creds
gh-scoped-credsProvide finely scoped push access to GitHub from a JupyterHub or
HPC system.GoalsAllow users on a JupyterHub to grant push access to onlyspecific
repositoriesrather thanallthe repositories they have access to.Do not store long-term credentials (like personal access tokens or
ssh-keys) on disk, as they may get archived / fall into the wrong
hands in the future.Allow GitHub organization admins visibility and control over what
repos users can push to from remote systems (like JupyterHub or a
shared cluster), where other admins of the remote system might
be able to access the files of users with push access to repos. This
has serious implications for supply chain security, as credentials
might be stolen or lost and serious vulnerabilities be pushed to
the repo.These goals are accomplished by:Creating aGitHub appspecific to the remote service (JupyterHub, HPC cluster, etc). Users
and GitHub organization admins can then provide fine grained, repo
level access to this GitHub app - Users can only push to repos that have the
app installed.A commandline tool (gh-scoped-creds) that lets specific users
authorize push access to the selected repositories temporarily - a token
that expires after 8 hours.An IPython Magic (%ghscopedcreds) that provides a convenient wrapper to callgh-scoped-credsfrom inside a Jupyter Notebook.In the future, an optional web app might also be provided to aid in
authentication.InstallationYou can installgh-scoped-credsfrom PyPI.pipinstallgh-scoped-credsGitHub App configurationCreate aGitHub appfor
use by the service (JupyterHub, HPC cluster, etc). You can either create
it under yourpersonal account,
or preferably under a GitHub organization account (Go to Settings ->
Developer Settings -> GitHub Apps -> New GitHub app from the organization's
GitHub page).Give it a descriptive name and description, as your users will see this
when they authenticate. Provide a link to a descriptive page explaining your
service (if you are using a JupyterHub, this could be just your JupyterHub URL).Select 'Enable Device Flow', as we rely on thedevice flowauthentication method.Disable webhooks (uncheck the 'Active' checkbox under 'Webhooks'). All other
textboxes can be left empty.Under 'Repository permissions', select 'Read & write' for 'Contents'. This
will provide users authenticating via the app just enough permissions to push
and pull from repositories.Under 'Where can this GitHub App be installed?', select 'Any account'. This will
enable users to push to their own user repositories or other organization repositaries,
rather than just the repos of the user or organization owning this GitHub app.Save theClient IDprovided in the information page of the app. You'll need this
in the client. Save thePublic linkas well, as users will need to use this to grant
access to particular repositories.Client configurationgh-scoped-credswill need to know the "Client ID" of the created GitHub app to
perform authentication. This can be either set with the environment variableGH_SCOPED_CREDS_CLIENT_ID, or be passed in as a commandline parameter--client-idto
thegh-scoped-credsscript when users use it to authenticate.Users will need to explicitly grant access to the repos they want to push to from
this particular JupyterHub or HPC system (see Usage section below). Admins can set
theGH_SCOPED_CREDS_APP_URLenvironment variable to inform users where to go
to manage this access -gh-scoped-credswill print this out after authentication.UsageGrant access to the GitHub appUsers will first need to go to the public page of the GitHub app, and
'Install' the app on their account and in organizations with repos they
want to push to. Wehighlyrecommend allowing access only to selected
repositories, and explicitly select the repositories this hosted service
(JupyterHub, HPC cluster, etc) should be able to push to. You can modify
this list afterwards, to make sure you only grant the required permissions.Given the common usage pattern where you are only pushing to a limited
set of repositories from a particular hosted service, this should hopefully
not be too cumborsome.Admins can set theGH_SCOPED_CREDS_APP_URLto thePublic Linkof the GitHub
app to make it easier for users to know where to go.Authenticate to GitHubThe hosted service must havegh-scoped-credsinstalled.Open a terminal, and typegh-scoped-creds. If you're in a Python based
Jupyter Notebook, you can also do:importgh_scoped_creds%ghscopedcredsThis will offer to open the page in a new window for you, and conveniently
copy the code you need to paste in the new window too.If you're on a non-containerized system (like a HPC), you must
also specify the path to put the credentials files in explicitly
with--git-credentials-path. The same path must be used in thegitconfigconfiguration mentioned earlier.It should give you a link to go to, and a code to input into the web page
when that link is opened. Open the link, enter the code there (the page accepts
pasting, so you can copy it from the output).Grant access to the device in the web page, and you're done!Authentication is valid for8 hours, and once it expires, this
process will need to be repeated. In the future, we might have a
web app or other process to make this less painful. However, keeping
the length of this session limited drastically helps with security too.AlternativesCreate an ssh key specifically for the hosted service (JupyterHub, HPC cluster, etc)
and add it to your GitHub account. If the key doesn't have a passphrase, this is
very insecure - anyone who can exfiltrate your key once can keep it and use it
whenever they wish. Even with a passphrase, the key can still be exfiltrated and
passphrase stolen when used. There's also no way to restrict which repositories
this can push to, which is a big issue.Create aPersonal Access Tokenand use that. This is a littlemoreinsecure than the ssh key, as it can be used
to make requests on your behalf too after being stolen! There is also no way to
restrict which repositories you can push to.Create aGitHub deploy keyfor each repository you want to push to, for each hosted service you want to push
from. While this lets you control which repos this ssh key can access, it is still
stored long term at risk and can be exfiltrated.