diff --git a/docs/source/getting-started/security-basics.rst b/docs/source/getting-started/security-basics.rst index 80996555..5da0a668 100644 --- a/docs/source/getting-started/security-basics.rst +++ b/docs/source/getting-started/security-basics.rst @@ -80,6 +80,49 @@ To achieve this, simply omit the configuration settings ``c.JupyterHub.ssl_key`` and ``c.JupyterHub.ssl_cert`` (setting them to ``None`` does not have the same effect, and is an error). +.. _authentication-token: + +Proxy authentication token +-------------------------- + +The Hub authenticates its requests to the Proxy using a secret token that +the Hub and Proxy agree upon. Note that this applies to the default +``ConfigurableHTTPProxy`` implementation. Not all proxy implementations +use an auth token. + +The value of this token should be a random string (for example, generated by +``openssl rand -hex 32``). You can store it in the configuration file or an +environment variable + +Generating and storing token in the configuration file +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can set the value in the configuration file, ``jupyterhub_config.py``: + +.. code-block:: python + + c.ConfigurableHTTPProxy.api_token = 'abc123...' # any random string + +Generating and storing as an environment variable +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can pass this value of the proxy authentication token to the Hub and Proxy +using the ``CONFIGPROXY_AUTH_TOKEN`` environment variable: + +.. code-block:: bash + + export CONFIGPROXY_AUTH_TOKEN=$(openssl rand -hex 32) + +This environment variable needs to be visible to the Hub and Proxy. + +Default if token is not set +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you don't set the Proxy authentication token, the Hub will generate a random +key itself, which means that any time you restart the Hub you **must also +restart the Proxy**. If the proxy is a subprocess of the Hub, this should happen +automatically (this is the default configuration). + .. _cookie-secret: Cookie secret @@ -146,41 +189,73 @@ itself, ``jupyterhub_config.py``, as a binary string: If the cookie secret value changes for the Hub, all single-user notebook servers must also be restarted. +.. _cookies: -.. _authentication-token: +Cookies used by JupyterHub authentication +----------------------------------------- -Proxy authentication token --------------------------- +The following cookies are used by the Hub for handling user authentication. -The Hub authenticates its requests to the Proxy using a secret token that -the Hub and Proxy agree upon. The value of this string should be a random -string (for example, generated by ``openssl rand -hex 32``). +This section was created based on this post_ from Discourse. -Generating and storing token in the configuration file -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. _post: https://discourse.jupyter.org/t/how-to-force-re-login-for-users/1998/6 -Or you can set the value in the configuration file, ``jupyterhub_config.py``: +jupyterhub-hub-login +~~~~~~~~~~~~~~~~~~~~ -.. code-block:: python +This is the login token used when visiting Hub-served pages that are +protected by authentication such as the main home, the spawn form, etc. +If this cookie is set, then the user is logged in. - c.JupyterHub.proxy_auth_token = '0bc02bede919e99a26de1e2a7a5aadfaf6228de836ec39a05a6c6942831d8fe5' +Resetting the Hub cookie secret effectively revokes this cookie. -Generating and storing as an environment variable -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +This cookie is restricted to the path ``/hub/``. -You can pass this value of the proxy authentication token to the Hub and Proxy -using the ``CONFIGPROXY_AUTH_TOKEN`` environment variable: +jupyterhub-user- +~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. code-block:: bash +This is the cookie used for authenticating with a single-user server. +It is set by the single-user server after OAuth with the Hub. - export CONFIGPROXY_AUTH_TOKEN=$(openssl rand -hex 32) +Effectively the same as ``jupyterhub-hub-login``, but for the +single-user server instead of the Hub. It contains an OAuth access token, +which is checked with the Hub to authenticate the browser. -This environment variable needs to be visible to the Hub and Proxy. +Each OAuth access token is associated with a session id (see ``jupyterhub-session-id`` section +below). -Default if token is not set -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +To avoid hitting the Hub on every request, the authentication response +is cached. And to avoid a stale cache the cache key is comprised of both +the token and session id. -If you don't set the Proxy authentication token, the Hub will generate a random -key itself, which means that any time you restart the Hub you **must also -restart the Proxy**. If the proxy is a subprocess of the Hub, this should happen -automatically (this is the default configuration). +Resetting the Hub cookie secret effectively revokes this cookie. + +This cookie is restricted to the path ``/user/``, so that +only the user’s server receives it. + +jupyterhub-session-id +~~~~~~~~~~~~~~~~~~~~~ + +This is a random string, meaningless in itself, and the only cookie +shared by the Hub and single-user servers. + +Its sole purpose is to to coordinate logout of the multiple OAuth cookies. + +This cookie is set to ``/`` so all endpoints can receive it, or clear it, etc. + +jupyterhub-user--oauth-state +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A short-lived cookie, used solely to store and validate OAuth state. +It is only set while OAuth between the single-user server and the Hub +is processing. + +If you use your browser development tools, you should see this cookie +for a very brief moment before your are logged in, +with an expiration date shorter than ``jupyterhub-hub-login`` or +``jupyterhub-user-``. + +This cookie should not exist after you have successfully logged in. + +This cookie is restricted to the path ``/user/``, so that only +the user’s server receives it.