--- /srv/reproducible-results/rbuild-debian/r-b-build.ju4Amd1l/b1/jupyterhub_5.2.1+ds1-4_amd64.changes +++ /srv/reproducible-results/rbuild-debian/r-b-build.ju4Amd1l/b2/jupyterhub_5.2.1+ds1-4_amd64.changes ├── Files │ @@ -1,2 +1,2 @@ │ │ - 2eb7de85c697d3d61390a79e3cd5f0cf 2022684 python optional jupyterhub_5.2.1+ds1-4_all.deb │ + aea1c2076e2501fd2da17f8976d9bfff 2022444 python optional jupyterhub_5.2.1+ds1-4_all.deb ├── jupyterhub_5.2.1+ds1-4_all.deb │ ├── file list │ │ @@ -1,3 +1,3 @@ │ │ -rw-r--r-- 0 0 0 4 2025-05-28 09:40:25.000000 debian-binary │ │ --rw-r--r-- 0 0 0 59500 2025-05-28 09:40:25.000000 control.tar.xz │ │ --rw-r--r-- 0 0 0 1962992 2025-05-28 09:40:25.000000 data.tar.xz │ │ +-rw-r--r-- 0 0 0 59496 2025-05-28 09:40:25.000000 control.tar.xz │ │ +-rw-r--r-- 0 0 0 1962756 2025-05-28 09:40:25.000000 data.tar.xz │ ├── control.tar.xz │ │ ├── control.tar │ │ │ ├── ./md5sums │ │ │ │ ├── ./md5sums │ │ │ │ │┄ Files differ │ ├── data.tar.xz │ │ ├── data.tar │ │ │ ├── ./usr/share/jupyterhub/jupyterhub_config.py │ │ │ │ @@ -1469,206 +1469,14 @@ │ │ │ │ # respond. Callers of spawner.start will assume that startup has failed if it │ │ │ │ # takes longer than this. start should return when the server process is started │ │ │ │ # and its location is known. │ │ │ │ # Default: 60 │ │ │ │ # c.Spawner.start_timeout = 60 │ │ │ │ │ │ │ │ #------------------------------------------------------------------------------ │ │ │ │ -# LocalProcessSpawner(Spawner) configuration │ │ │ │ -#------------------------------------------------------------------------------ │ │ │ │ -## A Spawner that uses `subprocess.Popen` to start single-user servers as local │ │ │ │ -# processes. │ │ │ │ -# │ │ │ │ -# Requires local UNIX users matching the authenticated users to exist. Does not │ │ │ │ -# work on Windows. │ │ │ │ -# │ │ │ │ -# This is the default spawner for JupyterHub. │ │ │ │ -# │ │ │ │ -# Note: This spawner does not implement CPU / memory guarantees and limits. │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Spawner.args │ │ │ │ -# c.LocalProcessSpawner.args = [] │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Spawner.auth_state_hook │ │ │ │ -# c.LocalProcessSpawner.auth_state_hook = None │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Spawner.cmd │ │ │ │ -# c.LocalProcessSpawner.cmd = ['jupyterhub-singleuser'] │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Spawner.consecutive_failure_limit │ │ │ │ -# c.LocalProcessSpawner.consecutive_failure_limit = 0 │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Spawner.cpu_guarantee │ │ │ │ -# c.LocalProcessSpawner.cpu_guarantee = None │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Spawner.cpu_limit │ │ │ │ -# c.LocalProcessSpawner.cpu_limit = None │ │ │ │ - │ │ │ │ -## Enable debug-logging of the single-user server │ │ │ │ -# See also: Spawner.debug │ │ │ │ -# c.LocalProcessSpawner.debug = False │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Spawner.default_url │ │ │ │ -# c.LocalProcessSpawner.default_url = '' │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Spawner.disable_user_config │ │ │ │ -# c.LocalProcessSpawner.disable_user_config = False │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Spawner.env_keep │ │ │ │ -# c.LocalProcessSpawner.env_keep = ['JUPYTERHUB_SINGLEUSER_APP'] │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Spawner.environment │ │ │ │ -# c.LocalProcessSpawner.environment = {} │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Spawner.group_overrides │ │ │ │ -# c.LocalProcessSpawner.group_overrides = traitlets.Undefined │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Spawner.http_timeout │ │ │ │ -# c.LocalProcessSpawner.http_timeout = 30 │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Spawner.hub_connect_url │ │ │ │ -# c.LocalProcessSpawner.hub_connect_url = None │ │ │ │ - │ │ │ │ -## Seconds to wait for single-user server process to halt after SIGINT. │ │ │ │ -# │ │ │ │ -# If the process has not exited cleanly after this many seconds, a SIGTERM is │ │ │ │ -# sent. │ │ │ │ -# Default: 10 │ │ │ │ -# c.LocalProcessSpawner.interrupt_timeout = 10 │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Spawner.ip │ │ │ │ -# c.LocalProcessSpawner.ip = '127.0.0.1' │ │ │ │ - │ │ │ │ -## Seconds to wait for process to halt after SIGKILL before giving up. │ │ │ │ -# │ │ │ │ -# If the process does not exit cleanly after this many seconds of SIGKILL, it │ │ │ │ -# becomes a zombie process. The hub process will log a warning and then give up. │ │ │ │ -# Default: 5 │ │ │ │ -# c.LocalProcessSpawner.kill_timeout = 5 │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Spawner.mem_guarantee │ │ │ │ -# c.LocalProcessSpawner.mem_guarantee = None │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Spawner.mem_limit │ │ │ │ -# c.LocalProcessSpawner.mem_limit = None │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Spawner.notebook_dir │ │ │ │ -# c.LocalProcessSpawner.notebook_dir = '' │ │ │ │ - │ │ │ │ -## Allowed scopes for oauth tokens issued by this server's oauth client. │ │ │ │ -# See also: Spawner.oauth_client_allowed_scopes │ │ │ │ -# c.LocalProcessSpawner.oauth_client_allowed_scopes = traitlets.Undefined │ │ │ │ - │ │ │ │ -## Allowed roles for oauth tokens. │ │ │ │ -# See also: Spawner.oauth_roles │ │ │ │ -# c.LocalProcessSpawner.oauth_roles = traitlets.Undefined │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Spawner.options_form │ │ │ │ -# c.LocalProcessSpawner.options_form = traitlets.Undefined │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Spawner.options_from_form │ │ │ │ -# c.LocalProcessSpawner.options_from_form = traitlets.Undefined │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Spawner.poll_interval │ │ │ │ -# c.LocalProcessSpawner.poll_interval = 30 │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Spawner.poll_jitter │ │ │ │ -# c.LocalProcessSpawner.poll_jitter = 0.1 │ │ │ │ - │ │ │ │ -## Extra keyword arguments to pass to Popen │ │ │ │ -# │ │ │ │ -# when spawning single-user servers. │ │ │ │ -# │ │ │ │ -# For example:: │ │ │ │ -# │ │ │ │ -# popen_kwargs = dict(shell=True) │ │ │ │ -# Default: {} │ │ │ │ -# c.LocalProcessSpawner.popen_kwargs = {} │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Spawner.port │ │ │ │ -# c.LocalProcessSpawner.port = 0 │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Spawner.post_stop_hook │ │ │ │ -# c.LocalProcessSpawner.post_stop_hook = None │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Spawner.pre_spawn_hook │ │ │ │ -# c.LocalProcessSpawner.pre_spawn_hook = None │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Spawner.progress_ready_hook │ │ │ │ -# c.LocalProcessSpawner.progress_ready_hook = None │ │ │ │ - │ │ │ │ -## The list of scopes to request for $JUPYTERHUB_API_TOKEN │ │ │ │ -# See also: Spawner.server_token_scopes │ │ │ │ -# c.LocalProcessSpawner.server_token_scopes = traitlets.Undefined │ │ │ │ - │ │ │ │ -## Specify a shell command to launch. │ │ │ │ -# │ │ │ │ -# The single-user command will be appended to this list, │ │ │ │ -# so it sould end with `-c` (for bash) or equivalent. │ │ │ │ -# │ │ │ │ -# For example:: │ │ │ │ -# │ │ │ │ -# c.LocalProcessSpawner.shell_cmd = ['bash', '-l', '-c'] │ │ │ │ -# │ │ │ │ -# to launch with a bash login shell, which would set up the user's own │ │ │ │ -# complete environment. │ │ │ │ -# │ │ │ │ -# .. warning:: │ │ │ │ -# │ │ │ │ -# Using shell_cmd gives users control over PATH, etc., │ │ │ │ -# which could change what the jupyterhub-singleuser launch command does. │ │ │ │ -# Only use this for trusted users. │ │ │ │ -# Default: [] │ │ │ │ -# c.LocalProcessSpawner.shell_cmd = [] │ │ │ │ - │ │ │ │ -## List of SSL alt names │ │ │ │ -# See also: Spawner.ssl_alt_names │ │ │ │ -# c.LocalProcessSpawner.ssl_alt_names = [] │ │ │ │ - │ │ │ │ -## Whether to include `DNS:localhost`, `IP:127.0.0.1` in alt names │ │ │ │ -# See also: Spawner.ssl_alt_names_include_local │ │ │ │ -# c.LocalProcessSpawner.ssl_alt_names_include_local = True │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Spawner.start_timeout │ │ │ │ -# c.LocalProcessSpawner.start_timeout = 60 │ │ │ │ - │ │ │ │ -## Seconds to wait for single-user server process to halt after SIGTERM. │ │ │ │ -# │ │ │ │ -# If the process does not exit cleanly after this many seconds of SIGTERM, a │ │ │ │ -# SIGKILL is sent. │ │ │ │ -# Default: 5 │ │ │ │ -# c.LocalProcessSpawner.term_timeout = 5 │ │ │ │ - │ │ │ │ -#------------------------------------------------------------------------------ │ │ │ │ # Authenticator(LoggingConfigurable) configuration │ │ │ │ #------------------------------------------------------------------------------ │ │ │ │ ## Base class for implementing an authentication provider for JupyterHub │ │ │ │ │ │ │ │ ## Set of users that will be granted admin rights on this JupyterHub. │ │ │ │ # │ │ │ │ # Note: │ │ │ │ @@ -2014,130 +1822,337 @@ │ │ │ │ # c.Authenticator.username_pattern = '' │ │ │ │ │ │ │ │ ## Deprecated, use `Authenticator.allowed_users` │ │ │ │ # Default: set() │ │ │ │ # c.Authenticator.whitelist = set() │ │ │ │ │ │ │ │ #------------------------------------------------------------------------------ │ │ │ │ -# DummyAuthenticator(Authenticator) configuration │ │ │ │ +# LocalAuthenticator(Authenticator) configuration │ │ │ │ #------------------------------------------------------------------------------ │ │ │ │ -## Dummy Authenticator for testing │ │ │ │ +## Base class for Authenticators that work with local Linux/UNIX users │ │ │ │ # │ │ │ │ -# By default, any username + password is allowed If a non-empty password is set, │ │ │ │ -# any username will be allowed if it logs in with that password. │ │ │ │ +# Checks for local users, and can attempt to create them if they exist. │ │ │ │ + │ │ │ │ +## The command to use for creating users as a list of strings │ │ │ │ # │ │ │ │ -# .. versionadded:: 1.0 │ │ │ │ +# For each element in the list, the string USERNAME will be replaced with the │ │ │ │ +# user's username. The username will also be appended as the final argument. │ │ │ │ # │ │ │ │ -# .. versionadded:: 5.0 │ │ │ │ -# `allow_all` defaults to True, │ │ │ │ -# preserving default behavior. │ │ │ │ +# For Linux, the default value is: │ │ │ │ +# │ │ │ │ +# ['adduser', '-q', '--gecos', '""', '--disabled-password'] │ │ │ │ +# │ │ │ │ +# To specify a custom home directory, set this to: │ │ │ │ +# │ │ │ │ +# ['adduser', '-q', '--gecos', '""', '--home', '/customhome/USERNAME', '-- │ │ │ │ +# disabled-password'] │ │ │ │ +# │ │ │ │ +# This will run the command: │ │ │ │ +# │ │ │ │ +# adduser -q --gecos "" --home /customhome/river --disabled-password river │ │ │ │ +# │ │ │ │ +# when the user 'river' is created. │ │ │ │ +# Default: [] │ │ │ │ +# c.LocalAuthenticator.add_user_cmd = [] │ │ │ │ │ │ │ │ ## │ │ │ │ # See also: Authenticator.admin_users │ │ │ │ -# c.DummyAuthenticator.admin_users = set() │ │ │ │ +# c.LocalAuthenticator.admin_users = set() │ │ │ │ │ │ │ │ ## │ │ │ │ # See also: Authenticator.allow_all │ │ │ │ -# c.DummyAuthenticator.allow_all = False │ │ │ │ +# c.LocalAuthenticator.allow_all = False │ │ │ │ │ │ │ │ ## │ │ │ │ # See also: Authenticator.allow_existing_users │ │ │ │ -# c.DummyAuthenticator.allow_existing_users = False │ │ │ │ +# c.LocalAuthenticator.allow_existing_users = False │ │ │ │ + │ │ │ │ +## Allow login from all users in these UNIX groups. │ │ │ │ +# │ │ │ │ +# .. versionchanged:: 5.0 │ │ │ │ +# `allowed_groups` may be specified together with allowed_users, │ │ │ │ +# to grant access by group OR name. │ │ │ │ +# Default: set() │ │ │ │ +# c.LocalAuthenticator.allowed_groups = set() │ │ │ │ │ │ │ │ ## │ │ │ │ # See also: Authenticator.allowed_users │ │ │ │ -# c.DummyAuthenticator.allowed_users = set() │ │ │ │ +# c.LocalAuthenticator.allowed_users = set() │ │ │ │ │ │ │ │ ## Is there any allow config? │ │ │ │ # See also: Authenticator.any_allow_config │ │ │ │ -# c.DummyAuthenticator.any_allow_config = False │ │ │ │ +# c.LocalAuthenticator.any_allow_config = False │ │ │ │ │ │ │ │ ## The max age (in seconds) of authentication info │ │ │ │ # See also: Authenticator.auth_refresh_age │ │ │ │ -# c.DummyAuthenticator.auth_refresh_age = 300 │ │ │ │ +# c.LocalAuthenticator.auth_refresh_age = 300 │ │ │ │ │ │ │ │ ## Automatically begin the login process │ │ │ │ # See also: Authenticator.auto_login │ │ │ │ -# c.DummyAuthenticator.auto_login = False │ │ │ │ +# c.LocalAuthenticator.auto_login = False │ │ │ │ │ │ │ │ ## │ │ │ │ # See also: Authenticator.auto_login_oauth2_authorize │ │ │ │ -# c.DummyAuthenticator.auto_login_oauth2_authorize = False │ │ │ │ +# c.LocalAuthenticator.auto_login_oauth2_authorize = False │ │ │ │ │ │ │ │ ## │ │ │ │ # See also: Authenticator.blocked_users │ │ │ │ -# c.DummyAuthenticator.blocked_users = set() │ │ │ │ +# c.LocalAuthenticator.blocked_users = set() │ │ │ │ + │ │ │ │ +## If set to True, will attempt to create local system users if they do not exist │ │ │ │ +# already. │ │ │ │ +# │ │ │ │ +# Supports Linux and BSD variants only. │ │ │ │ +# Default: False │ │ │ │ +# c.LocalAuthenticator.create_system_users = False │ │ │ │ │ │ │ │ ## Delete any users from the database that do not pass validation │ │ │ │ # See also: Authenticator.delete_invalid_users │ │ │ │ -# c.DummyAuthenticator.delete_invalid_users = False │ │ │ │ +# c.LocalAuthenticator.delete_invalid_users = False │ │ │ │ │ │ │ │ ## Enable persisting auth_state (if available). │ │ │ │ # See also: Authenticator.enable_auth_state │ │ │ │ -# c.DummyAuthenticator.enable_auth_state = False │ │ │ │ +# c.LocalAuthenticator.enable_auth_state = False │ │ │ │ + │ │ │ │ +## DEPRECATED: use allowed_groups │ │ │ │ +# Default: set() │ │ │ │ +# c.LocalAuthenticator.group_whitelist = set() │ │ │ │ │ │ │ │ ## Let authenticator manage user groups │ │ │ │ # See also: Authenticator.manage_groups │ │ │ │ -# c.DummyAuthenticator.manage_groups = False │ │ │ │ +# c.LocalAuthenticator.manage_groups = False │ │ │ │ │ │ │ │ ## Let authenticator manage roles │ │ │ │ # See also: Authenticator.manage_roles │ │ │ │ -# c.DummyAuthenticator.manage_roles = False │ │ │ │ +# c.LocalAuthenticator.manage_roles = False │ │ │ │ │ │ │ │ ## │ │ │ │ # See also: Authenticator.otp_prompt │ │ │ │ -# c.DummyAuthenticator.otp_prompt = 'OTP:' │ │ │ │ +# c.LocalAuthenticator.otp_prompt = 'OTP:' │ │ │ │ │ │ │ │ -## Set a global password for all users wanting to log in. │ │ │ │ +## │ │ │ │ +# See also: Authenticator.post_auth_hook │ │ │ │ +# c.LocalAuthenticator.post_auth_hook = None │ │ │ │ + │ │ │ │ +## Force refresh of auth prior to spawn. │ │ │ │ +# See also: Authenticator.refresh_pre_spawn │ │ │ │ +# c.LocalAuthenticator.refresh_pre_spawn = False │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: Authenticator.request_otp │ │ │ │ +# c.LocalAuthenticator.request_otp = False │ │ │ │ + │ │ │ │ +## Reset managed roles to result of `load_managed_roles()` on startup. │ │ │ │ +# See also: Authenticator.reset_managed_roles_on_startup │ │ │ │ +# c.LocalAuthenticator.reset_managed_roles_on_startup = False │ │ │ │ + │ │ │ │ +## Dictionary of uids to use at user creation time. This helps ensure that users │ │ │ │ +# created from the database get the same uid each time they are created in │ │ │ │ +# temporary deployments or containers. │ │ │ │ +# Default: {} │ │ │ │ +# c.LocalAuthenticator.uids = {} │ │ │ │ + │ │ │ │ +## Dictionary mapping authenticator usernames to JupyterHub users. │ │ │ │ +# See also: Authenticator.username_map │ │ │ │ +# c.LocalAuthenticator.username_map = {} │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: Authenticator.username_pattern │ │ │ │ +# c.LocalAuthenticator.username_pattern = '' │ │ │ │ + │ │ │ │ +## Deprecated, use `Authenticator.allowed_users` │ │ │ │ +# See also: Authenticator.whitelist │ │ │ │ +# c.LocalAuthenticator.whitelist = set() │ │ │ │ + │ │ │ │ +#------------------------------------------------------------------------------ │ │ │ │ +# PAMAuthenticator(LocalAuthenticator) configuration │ │ │ │ +#------------------------------------------------------------------------------ │ │ │ │ +## Authenticate local UNIX users with PAM │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: LocalAuthenticator.add_user_cmd │ │ │ │ +# c.PAMAuthenticator.add_user_cmd = [] │ │ │ │ + │ │ │ │ +## Authoritative list of user groups that determine admin access. Users not in │ │ │ │ +# these groups can still be granted admin status through admin_users. │ │ │ │ # │ │ │ │ -# This allows users with any username to log in with the same static password. │ │ │ │ -# Default: '' │ │ │ │ -# c.DummyAuthenticator.password = '' │ │ │ │ +# allowed/blocked rules still apply. │ │ │ │ +# │ │ │ │ +# Note: As of JupyterHub 2.0, full admin rights should not be required, and more │ │ │ │ +# precise permissions can be managed via roles. │ │ │ │ +# Default: set() │ │ │ │ +# c.PAMAuthenticator.admin_groups = set() │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: Authenticator.admin_users │ │ │ │ +# c.PAMAuthenticator.admin_users = set() │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: Authenticator.allow_all │ │ │ │ +# c.PAMAuthenticator.allow_all = False │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: Authenticator.allow_existing_users │ │ │ │ +# c.PAMAuthenticator.allow_existing_users = False │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: LocalAuthenticator.allowed_groups │ │ │ │ +# c.PAMAuthenticator.allowed_groups = set() │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: Authenticator.allowed_users │ │ │ │ +# c.PAMAuthenticator.allowed_users = set() │ │ │ │ + │ │ │ │ +## Is there any allow config? │ │ │ │ +# See also: Authenticator.any_allow_config │ │ │ │ +# c.PAMAuthenticator.any_allow_config = False │ │ │ │ + │ │ │ │ +## The max age (in seconds) of authentication info │ │ │ │ +# See also: Authenticator.auth_refresh_age │ │ │ │ +# c.PAMAuthenticator.auth_refresh_age = 300 │ │ │ │ + │ │ │ │ +## Automatically begin the login process │ │ │ │ +# See also: Authenticator.auto_login │ │ │ │ +# c.PAMAuthenticator.auto_login = False │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: Authenticator.auto_login_oauth2_authorize │ │ │ │ +# c.PAMAuthenticator.auto_login_oauth2_authorize = False │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: Authenticator.blocked_users │ │ │ │ +# c.PAMAuthenticator.blocked_users = set() │ │ │ │ + │ │ │ │ +## Whether to check the user's account status via PAM during authentication. │ │ │ │ +# │ │ │ │ +# The PAM account stack performs non-authentication based account management. It │ │ │ │ +# is typically used to restrict/permit access to a service and this step is │ │ │ │ +# needed to access the host's user access control. │ │ │ │ +# │ │ │ │ +# Disabling this can be dangerous as authenticated but unauthorized users may be │ │ │ │ +# granted access and, therefore, arbitrary execution on the system. │ │ │ │ +# Default: True │ │ │ │ +# c.PAMAuthenticator.check_account = True │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: LocalAuthenticator.create_system_users │ │ │ │ +# c.PAMAuthenticator.create_system_users = False │ │ │ │ + │ │ │ │ +## Delete any users from the database that do not pass validation │ │ │ │ +# See also: Authenticator.delete_invalid_users │ │ │ │ +# c.PAMAuthenticator.delete_invalid_users = False │ │ │ │ + │ │ │ │ +## Enable persisting auth_state (if available). │ │ │ │ +# See also: Authenticator.enable_auth_state │ │ │ │ +# c.PAMAuthenticator.enable_auth_state = False │ │ │ │ + │ │ │ │ +## The text encoding to use when communicating with PAM │ │ │ │ +# Default: 'utf8' │ │ │ │ +# c.PAMAuthenticator.encoding = 'utf8' │ │ │ │ + │ │ │ │ +## Number of executor threads. │ │ │ │ +# │ │ │ │ +# PAM auth requests happen in this thread, so it is mostly waiting for the pam │ │ │ │ +# stack. One thread is usually enough, unless your pam stack is doing something │ │ │ │ +# slow like network requests │ │ │ │ +# Default: 4 │ │ │ │ +# c.PAMAuthenticator.executor_threads = 4 │ │ │ │ + │ │ │ │ +## DEPRECATED: use allowed_groups │ │ │ │ +# See also: LocalAuthenticator.group_whitelist │ │ │ │ +# c.PAMAuthenticator.group_whitelist = set() │ │ │ │ + │ │ │ │ +## Let authenticator manage user groups │ │ │ │ +# See also: Authenticator.manage_groups │ │ │ │ +# c.PAMAuthenticator.manage_groups = False │ │ │ │ + │ │ │ │ +## Let authenticator manage roles │ │ │ │ +# See also: Authenticator.manage_roles │ │ │ │ +# c.PAMAuthenticator.manage_roles = False │ │ │ │ + │ │ │ │ +## Whether to open a new PAM session when spawners are started. │ │ │ │ +# │ │ │ │ +# This may trigger things like mounting shared filesystems, loading credentials, │ │ │ │ +# etc. depending on system configuration. │ │ │ │ +# │ │ │ │ +# The lifecycle of PAM sessions is not correct, so many PAM session │ │ │ │ +# configurations will not work. │ │ │ │ +# │ │ │ │ +# If any errors are encountered when opening/closing PAM sessions, this is │ │ │ │ +# automatically set to False. │ │ │ │ +# │ │ │ │ +# .. versionchanged:: 2.2 │ │ │ │ +# │ │ │ │ +# Due to longstanding problems in the session lifecycle, │ │ │ │ +# this is now disabled by default. │ │ │ │ +# You may opt-in to opening sessions by setting this to True. │ │ │ │ +# Default: False │ │ │ │ +# c.PAMAuthenticator.open_sessions = False │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: Authenticator.otp_prompt │ │ │ │ +# c.PAMAuthenticator.otp_prompt = 'OTP:' │ │ │ │ + │ │ │ │ +## Round-trip the username via PAM lookups to make sure it is unique │ │ │ │ +# │ │ │ │ +# PAM can accept multiple usernames that map to the same user, for example │ │ │ │ +# DOMAIN\username in some cases. To prevent this, convert username into uid, │ │ │ │ +# then back to uid to normalize. │ │ │ │ +# Default: False │ │ │ │ +# c.PAMAuthenticator.pam_normalize_username = False │ │ │ │ │ │ │ │ ## │ │ │ │ # See also: Authenticator.post_auth_hook │ │ │ │ -# c.DummyAuthenticator.post_auth_hook = None │ │ │ │ +# c.PAMAuthenticator.post_auth_hook = None │ │ │ │ │ │ │ │ ## Force refresh of auth prior to spawn. │ │ │ │ # See also: Authenticator.refresh_pre_spawn │ │ │ │ -# c.DummyAuthenticator.refresh_pre_spawn = False │ │ │ │ +# c.PAMAuthenticator.refresh_pre_spawn = False │ │ │ │ │ │ │ │ ## │ │ │ │ # See also: Authenticator.request_otp │ │ │ │ -# c.DummyAuthenticator.request_otp = False │ │ │ │ +# c.PAMAuthenticator.request_otp = False │ │ │ │ │ │ │ │ ## Reset managed roles to result of `load_managed_roles()` on startup. │ │ │ │ # See also: Authenticator.reset_managed_roles_on_startup │ │ │ │ -# c.DummyAuthenticator.reset_managed_roles_on_startup = False │ │ │ │ +# c.PAMAuthenticator.reset_managed_roles_on_startup = False │ │ │ │ + │ │ │ │ +## The name of the PAM service to use for authentication │ │ │ │ +# Default: 'login' │ │ │ │ +# c.PAMAuthenticator.service = 'login' │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: LocalAuthenticator.uids │ │ │ │ +# c.PAMAuthenticator.uids = {} │ │ │ │ │ │ │ │ ## Dictionary mapping authenticator usernames to JupyterHub users. │ │ │ │ # See also: Authenticator.username_map │ │ │ │ -# c.DummyAuthenticator.username_map = {} │ │ │ │ +# c.PAMAuthenticator.username_map = {} │ │ │ │ │ │ │ │ ## │ │ │ │ # See also: Authenticator.username_pattern │ │ │ │ -# c.DummyAuthenticator.username_pattern = '' │ │ │ │ +# c.PAMAuthenticator.username_pattern = '' │ │ │ │ │ │ │ │ ## Deprecated, use `Authenticator.allowed_users` │ │ │ │ # See also: Authenticator.whitelist │ │ │ │ -# c.DummyAuthenticator.whitelist = set() │ │ │ │ +# c.PAMAuthenticator.whitelist = set() │ │ │ │ │ │ │ │ #------------------------------------------------------------------------------ │ │ │ │ # CryptKeeper(SingletonConfigurable) configuration │ │ │ │ #------------------------------------------------------------------------------ │ │ │ │ ## Encapsulate encryption configuration │ │ │ │ # │ │ │ │ # Use via the encryption_config singleton below. │ │ │ │ │ │ │ │ # Default: [] │ │ │ │ # c.CryptKeeper.keys = [] │ │ │ │ │ │ │ │ ## The number of threads to allocate for encryption │ │ │ │ -# Default: 42 │ │ │ │ -# c.CryptKeeper.n_threads = 42 │ │ │ │ +# Default: 40 │ │ │ │ +# c.CryptKeeper.n_threads = 40 │ │ │ │ │ │ │ │ #------------------------------------------------------------------------------ │ │ │ │ # NullAuthenticator(Authenticator) configuration │ │ │ │ #------------------------------------------------------------------------------ │ │ │ │ ## Null Authenticator for JupyterHub │ │ │ │ # │ │ │ │ # For cases where authentication should be disabled, e.g. only allowing access │ │ │ │ @@ -2222,118 +2237,204 @@ │ │ │ │ # c.NullAuthenticator.username_pattern = '' │ │ │ │ │ │ │ │ ## Deprecated, use `Authenticator.allowed_users` │ │ │ │ # See also: Authenticator.whitelist │ │ │ │ # c.NullAuthenticator.whitelist = set() │ │ │ │ │ │ │ │ #------------------------------------------------------------------------------ │ │ │ │ -# Proxy(LoggingConfigurable) configuration │ │ │ │ +# LocalProcessSpawner(Spawner) configuration │ │ │ │ #------------------------------------------------------------------------------ │ │ │ │ -## Base class for configurable proxies that JupyterHub can use. │ │ │ │ -# │ │ │ │ -# A proxy implementation should subclass this and must define the following │ │ │ │ -# methods: │ │ │ │ -# │ │ │ │ -# - :meth:`.get_all_routes` return a dictionary of all JupyterHub-related routes │ │ │ │ -# - :meth:`.add_route` adds a route - :meth:`.delete_route` deletes a route │ │ │ │ -# │ │ │ │ -# In addition to these, the following method(s) may need to be implemented: │ │ │ │ +## A Spawner that uses `subprocess.Popen` to start single-user servers as local │ │ │ │ +# processes. │ │ │ │ # │ │ │ │ -# - :meth:`.start` start the proxy, if it should be launched by the Hub │ │ │ │ -# instead of externally managed. │ │ │ │ -# If the proxy is externally managed, it should set :attr:`should_start` to False. │ │ │ │ -# - :meth:`.stop` stop the proxy. Only used if :meth:`.start` is also used. │ │ │ │ +# Requires local UNIX users matching the authenticated users to exist. Does not │ │ │ │ +# work on Windows. │ │ │ │ # │ │ │ │ -# And the following method(s) are optional, but can be provided: │ │ │ │ +# This is the default spawner for JupyterHub. │ │ │ │ # │ │ │ │ -# - :meth:`.get_route` gets a single route. │ │ │ │ -# There is a default implementation that extracts data from :meth:`.get_all_routes`, │ │ │ │ -# but implementations may choose to provide a more efficient implementation │ │ │ │ -# of fetching a single route. │ │ │ │ +# Note: This spawner does not implement CPU / memory guarantees and limits. │ │ │ │ │ │ │ │ -## Additional routes to be maintained in the proxy. │ │ │ │ -# │ │ │ │ -# A dictionary with a route specification as key, and a URL as target. The hub │ │ │ │ -# will ensure this route is present in the proxy. │ │ │ │ -# │ │ │ │ -# If the hub is running in host based mode (with JupyterHub.subdomain_host set), │ │ │ │ -# the routespec *must* have a domain component (example.com/my-url/). If the hub │ │ │ │ -# is not running in host based mode, the routespec *must not* have a domain │ │ │ │ -# component (/my-url/). │ │ │ │ +## │ │ │ │ +# See also: Spawner.args │ │ │ │ +# c.LocalProcessSpawner.args = [] │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: Spawner.auth_state_hook │ │ │ │ +# c.LocalProcessSpawner.auth_state_hook = None │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: Spawner.cmd │ │ │ │ +# c.LocalProcessSpawner.cmd = ['jupyterhub-singleuser'] │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: Spawner.consecutive_failure_limit │ │ │ │ +# c.LocalProcessSpawner.consecutive_failure_limit = 0 │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: Spawner.cpu_guarantee │ │ │ │ +# c.LocalProcessSpawner.cpu_guarantee = None │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: Spawner.cpu_limit │ │ │ │ +# c.LocalProcessSpawner.cpu_limit = None │ │ │ │ + │ │ │ │ +## Enable debug-logging of the single-user server │ │ │ │ +# See also: Spawner.debug │ │ │ │ +# c.LocalProcessSpawner.debug = False │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: Spawner.default_url │ │ │ │ +# c.LocalProcessSpawner.default_url = '' │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: Spawner.disable_user_config │ │ │ │ +# c.LocalProcessSpawner.disable_user_config = False │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: Spawner.env_keep │ │ │ │ +# c.LocalProcessSpawner.env_keep = ['JUPYTERHUB_SINGLEUSER_APP'] │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: Spawner.environment │ │ │ │ +# c.LocalProcessSpawner.environment = {} │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: Spawner.group_overrides │ │ │ │ +# c.LocalProcessSpawner.group_overrides = traitlets.Undefined │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: Spawner.http_timeout │ │ │ │ +# c.LocalProcessSpawner.http_timeout = 30 │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: Spawner.hub_connect_url │ │ │ │ +# c.LocalProcessSpawner.hub_connect_url = None │ │ │ │ + │ │ │ │ +## Seconds to wait for single-user server process to halt after SIGINT. │ │ │ │ # │ │ │ │ -# Helpful when the hub is running in API-only mode. │ │ │ │ -# Default: {} │ │ │ │ -# c.Proxy.extra_routes = {} │ │ │ │ +# If the process has not exited cleanly after this many seconds, a SIGTERM is │ │ │ │ +# sent. │ │ │ │ +# Default: 10 │ │ │ │ +# c.LocalProcessSpawner.interrupt_timeout = 10 │ │ │ │ │ │ │ │ -## Should the Hub start the proxy │ │ │ │ +## │ │ │ │ +# See also: Spawner.ip │ │ │ │ +# c.LocalProcessSpawner.ip = '127.0.0.1' │ │ │ │ + │ │ │ │ +## Seconds to wait for process to halt after SIGKILL before giving up. │ │ │ │ # │ │ │ │ -# If True, the Hub will start the proxy and stop it. │ │ │ │ -# Set to False if the proxy is managed externally, │ │ │ │ -# such as by systemd, docker, or another service manager. │ │ │ │ -# Default: True │ │ │ │ -# c.Proxy.should_start = True │ │ │ │ +# If the process does not exit cleanly after this many seconds of SIGKILL, it │ │ │ │ +# becomes a zombie process. The hub process will log a warning and then give up. │ │ │ │ +# Default: 5 │ │ │ │ +# c.LocalProcessSpawner.kill_timeout = 5 │ │ │ │ │ │ │ │ -#------------------------------------------------------------------------------ │ │ │ │ -# ConfigurableHTTPProxy(Proxy) configuration │ │ │ │ -#------------------------------------------------------------------------------ │ │ │ │ -## Proxy implementation for the default configurable-http-proxy. │ │ │ │ +## │ │ │ │ +# See also: Spawner.mem_guarantee │ │ │ │ +# c.LocalProcessSpawner.mem_guarantee = None │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: Spawner.mem_limit │ │ │ │ +# c.LocalProcessSpawner.mem_limit = None │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: Spawner.notebook_dir │ │ │ │ +# c.LocalProcessSpawner.notebook_dir = '' │ │ │ │ + │ │ │ │ +## Allowed scopes for oauth tokens issued by this server's oauth client. │ │ │ │ +# See also: Spawner.oauth_client_allowed_scopes │ │ │ │ +# c.LocalProcessSpawner.oauth_client_allowed_scopes = traitlets.Undefined │ │ │ │ + │ │ │ │ +## Allowed roles for oauth tokens. │ │ │ │ +# See also: Spawner.oauth_roles │ │ │ │ +# c.LocalProcessSpawner.oauth_roles = traitlets.Undefined │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: Spawner.options_form │ │ │ │ +# c.LocalProcessSpawner.options_form = traitlets.Undefined │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: Spawner.options_from_form │ │ │ │ +# c.LocalProcessSpawner.options_from_form = traitlets.Undefined │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: Spawner.poll_interval │ │ │ │ +# c.LocalProcessSpawner.poll_interval = 30 │ │ │ │ + │ │ │ │ +## │ │ │ │ +# See also: Spawner.poll_jitter │ │ │ │ +# c.LocalProcessSpawner.poll_jitter = 0.1 │ │ │ │ + │ │ │ │ +## Extra keyword arguments to pass to Popen │ │ │ │ # │ │ │ │ -# This is the default proxy implementation for running the nodejs proxy │ │ │ │ -# `configurable-http-proxy`. │ │ │ │ +# when spawning single-user servers. │ │ │ │ # │ │ │ │ -# If the proxy should not be run as a subprocess of the Hub, (e.g. in a separate │ │ │ │ -# container), set:: │ │ │ │ +# For example:: │ │ │ │ # │ │ │ │ -# c.ConfigurableHTTPProxy.should_start = False │ │ │ │ +# popen_kwargs = dict(shell=True) │ │ │ │ +# Default: {} │ │ │ │ +# c.LocalProcessSpawner.popen_kwargs = {} │ │ │ │ │ │ │ │ -## The ip (or hostname) of the proxy's API endpoint │ │ │ │ -# Default: '' │ │ │ │ -# c.ConfigurableHTTPProxy.api_url = '' │ │ │ │ +## │ │ │ │ +# See also: Spawner.port │ │ │ │ +# c.LocalProcessSpawner.port = 0 │ │ │ │ │ │ │ │ -## The Proxy auth token │ │ │ │ -# │ │ │ │ -# Loaded from the CONFIGPROXY_AUTH_TOKEN env variable by default. │ │ │ │ -# Default: '' │ │ │ │ -# c.ConfigurableHTTPProxy.auth_token = '' │ │ │ │ +## │ │ │ │ +# See also: Spawner.post_stop_hook │ │ │ │ +# c.LocalProcessSpawner.post_stop_hook = None │ │ │ │ │ │ │ │ -## Interval (in seconds) at which to check if the proxy is running. │ │ │ │ -# Default: 5 │ │ │ │ -# c.ConfigurableHTTPProxy.check_running_interval = 5 │ │ │ │ +## │ │ │ │ +# See also: Spawner.pre_spawn_hook │ │ │ │ +# c.LocalProcessSpawner.pre_spawn_hook = None │ │ │ │ │ │ │ │ -## The command to start the proxy │ │ │ │ -# Default: ['configurable-http-proxy'] │ │ │ │ -# c.ConfigurableHTTPProxy.command = ['configurable-http-proxy'] │ │ │ │ +## │ │ │ │ +# See also: Spawner.progress_ready_hook │ │ │ │ +# c.LocalProcessSpawner.progress_ready_hook = None │ │ │ │ │ │ │ │ -## The number of requests allowed to be concurrently outstanding to the proxy │ │ │ │ -# │ │ │ │ -# Limiting this number avoids potential timeout errors by sending too many │ │ │ │ -# requests to update the proxy at once │ │ │ │ -# Default: 10 │ │ │ │ -# c.ConfigurableHTTPProxy.concurrency = 10 │ │ │ │ +## The list of scopes to request for $JUPYTERHUB_API_TOKEN │ │ │ │ +# See also: Spawner.server_token_scopes │ │ │ │ +# c.LocalProcessSpawner.server_token_scopes = traitlets.Undefined │ │ │ │ │ │ │ │ -## Add debug-level logging to the Proxy. │ │ │ │ -# Default: False │ │ │ │ -# c.ConfigurableHTTPProxy.debug = False │ │ │ │ +## Specify a shell command to launch. │ │ │ │ +# │ │ │ │ +# The single-user command will be appended to this list, │ │ │ │ +# so it sould end with `-c` (for bash) or equivalent. │ │ │ │ +# │ │ │ │ +# For example:: │ │ │ │ +# │ │ │ │ +# c.LocalProcessSpawner.shell_cmd = ['bash', '-l', '-c'] │ │ │ │ +# │ │ │ │ +# to launch with a bash login shell, which would set up the user's own │ │ │ │ +# complete environment. │ │ │ │ +# │ │ │ │ +# .. warning:: │ │ │ │ +# │ │ │ │ +# Using shell_cmd gives users control over PATH, etc., │ │ │ │ +# which could change what the jupyterhub-singleuser launch command does. │ │ │ │ +# Only use this for trusted users. │ │ │ │ +# Default: [] │ │ │ │ +# c.LocalProcessSpawner.shell_cmd = [] │ │ │ │ │ │ │ │ -## │ │ │ │ -# See also: Proxy.extra_routes │ │ │ │ -# c.ConfigurableHTTPProxy.extra_routes = {} │ │ │ │ +## List of SSL alt names │ │ │ │ +# See also: Spawner.ssl_alt_names │ │ │ │ +# c.LocalProcessSpawner.ssl_alt_names = [] │ │ │ │ │ │ │ │ -## Proxy log level │ │ │ │ -# Choices: any of ['debug', 'info', 'warn', 'error'] (case-insensitive) │ │ │ │ -# Default: 'info' │ │ │ │ -# c.ConfigurableHTTPProxy.log_level = 'info' │ │ │ │ +## Whether to include `DNS:localhost`, `IP:127.0.0.1` in alt names │ │ │ │ +# See also: Spawner.ssl_alt_names_include_local │ │ │ │ +# c.LocalProcessSpawner.ssl_alt_names_include_local = True │ │ │ │ │ │ │ │ -## File in which to write the PID of the proxy process. │ │ │ │ -# Default: 'jupyterhub-proxy.pid' │ │ │ │ -# c.ConfigurableHTTPProxy.pid_file = 'jupyterhub-proxy.pid' │ │ │ │ +## │ │ │ │ +# See also: Spawner.start_timeout │ │ │ │ +# c.LocalProcessSpawner.start_timeout = 60 │ │ │ │ │ │ │ │ -## Should the Hub start the proxy │ │ │ │ -# See also: Proxy.should_start │ │ │ │ -# c.ConfigurableHTTPProxy.should_start = True │ │ │ │ +## Seconds to wait for single-user server process to halt after SIGTERM. │ │ │ │ +# │ │ │ │ +# If the process does not exit cleanly after this many seconds of SIGTERM, a │ │ │ │ +# SIGKILL is sent. │ │ │ │ +# Default: 5 │ │ │ │ +# c.LocalProcessSpawner.term_timeout = 5 │ │ │ │ │ │ │ │ #------------------------------------------------------------------------------ │ │ │ │ # SimpleLocalProcessSpawner(LocalProcessSpawner) configuration │ │ │ │ #------------------------------------------------------------------------------ │ │ │ │ ## A version of LocalProcessSpawner that doesn't require users to exist on the │ │ │ │ # system beforehand. │ │ │ │ # │ │ │ │ @@ -2492,316 +2593,215 @@ │ │ │ │ # c.SimpleLocalProcessSpawner.start_timeout = 60 │ │ │ │ │ │ │ │ ## │ │ │ │ # See also: LocalProcessSpawner.term_timeout │ │ │ │ # c.SimpleLocalProcessSpawner.term_timeout = 5 │ │ │ │ │ │ │ │ #------------------------------------------------------------------------------ │ │ │ │ -# LocalAuthenticator(Authenticator) configuration │ │ │ │ +# Proxy(LoggingConfigurable) configuration │ │ │ │ #------------------------------------------------------------------------------ │ │ │ │ -## Base class for Authenticators that work with local Linux/UNIX users │ │ │ │ +## Base class for configurable proxies that JupyterHub can use. │ │ │ │ # │ │ │ │ -# Checks for local users, and can attempt to create them if they exist. │ │ │ │ - │ │ │ │ -## The command to use for creating users as a list of strings │ │ │ │ +# A proxy implementation should subclass this and must define the following │ │ │ │ +# methods: │ │ │ │ # │ │ │ │ -# For each element in the list, the string USERNAME will be replaced with the │ │ │ │ -# user's username. The username will also be appended as the final argument. │ │ │ │ +# - :meth:`.get_all_routes` return a dictionary of all JupyterHub-related routes │ │ │ │ +# - :meth:`.add_route` adds a route - :meth:`.delete_route` deletes a route │ │ │ │ # │ │ │ │ -# For Linux, the default value is: │ │ │ │ +# In addition to these, the following method(s) may need to be implemented: │ │ │ │ # │ │ │ │ -# ['adduser', '-q', '--gecos', '""', '--disabled-password'] │ │ │ │ +# - :meth:`.start` start the proxy, if it should be launched by the Hub │ │ │ │ +# instead of externally managed. │ │ │ │ +# If the proxy is externally managed, it should set :attr:`should_start` to False. │ │ │ │ +# - :meth:`.stop` stop the proxy. Only used if :meth:`.start` is also used. │ │ │ │ # │ │ │ │ -# To specify a custom home directory, set this to: │ │ │ │ +# And the following method(s) are optional, but can be provided: │ │ │ │ # │ │ │ │ -# ['adduser', '-q', '--gecos', '""', '--home', '/customhome/USERNAME', '-- │ │ │ │ -# disabled-password'] │ │ │ │ +# - :meth:`.get_route` gets a single route. │ │ │ │ +# There is a default implementation that extracts data from :meth:`.get_all_routes`, │ │ │ │ +# but implementations may choose to provide a more efficient implementation │ │ │ │ +# of fetching a single route. │ │ │ │ + │ │ │ │ +## Additional routes to be maintained in the proxy. │ │ │ │ # │ │ │ │ -# This will run the command: │ │ │ │ +# A dictionary with a route specification as key, and a URL as target. The hub │ │ │ │ +# will ensure this route is present in the proxy. │ │ │ │ # │ │ │ │ -# adduser -q --gecos "" --home /customhome/river --disabled-password river │ │ │ │ +# If the hub is running in host based mode (with JupyterHub.subdomain_host set), │ │ │ │ +# the routespec *must* have a domain component (example.com/my-url/). If the hub │ │ │ │ +# is not running in host based mode, the routespec *must not* have a domain │ │ │ │ +# component (/my-url/). │ │ │ │ # │ │ │ │ -# when the user 'river' is created. │ │ │ │ -# Default: [] │ │ │ │ -# c.LocalAuthenticator.add_user_cmd = [] │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Authenticator.admin_users │ │ │ │ -# c.LocalAuthenticator.admin_users = set() │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Authenticator.allow_all │ │ │ │ -# c.LocalAuthenticator.allow_all = False │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Authenticator.allow_existing_users │ │ │ │ -# c.LocalAuthenticator.allow_existing_users = False │ │ │ │ +# Helpful when the hub is running in API-only mode. │ │ │ │ +# Default: {} │ │ │ │ +# c.Proxy.extra_routes = {} │ │ │ │ │ │ │ │ -## Allow login from all users in these UNIX groups. │ │ │ │ +## Should the Hub start the proxy │ │ │ │ # │ │ │ │ -# .. versionchanged:: 5.0 │ │ │ │ -# `allowed_groups` may be specified together with allowed_users, │ │ │ │ -# to grant access by group OR name. │ │ │ │ -# Default: set() │ │ │ │ -# c.LocalAuthenticator.allowed_groups = set() │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Authenticator.allowed_users │ │ │ │ -# c.LocalAuthenticator.allowed_users = set() │ │ │ │ - │ │ │ │ -## Is there any allow config? │ │ │ │ -# See also: Authenticator.any_allow_config │ │ │ │ -# c.LocalAuthenticator.any_allow_config = False │ │ │ │ - │ │ │ │ -## The max age (in seconds) of authentication info │ │ │ │ -# See also: Authenticator.auth_refresh_age │ │ │ │ -# c.LocalAuthenticator.auth_refresh_age = 300 │ │ │ │ - │ │ │ │ -## Automatically begin the login process │ │ │ │ -# See also: Authenticator.auto_login │ │ │ │ -# c.LocalAuthenticator.auto_login = False │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Authenticator.auto_login_oauth2_authorize │ │ │ │ -# c.LocalAuthenticator.auto_login_oauth2_authorize = False │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: Authenticator.blocked_users │ │ │ │ -# c.LocalAuthenticator.blocked_users = set() │ │ │ │ +# If True, the Hub will start the proxy and stop it. │ │ │ │ +# Set to False if the proxy is managed externally, │ │ │ │ +# such as by systemd, docker, or another service manager. │ │ │ │ +# Default: True │ │ │ │ +# c.Proxy.should_start = True │ │ │ │ │ │ │ │ -## If set to True, will attempt to create local system users if they do not exist │ │ │ │ -# already. │ │ │ │ +#------------------------------------------------------------------------------ │ │ │ │ +# ConfigurableHTTPProxy(Proxy) configuration │ │ │ │ +#------------------------------------------------------------------------------ │ │ │ │ +## Proxy implementation for the default configurable-http-proxy. │ │ │ │ # │ │ │ │ -# Supports Linux and BSD variants only. │ │ │ │ -# Default: False │ │ │ │ -# c.LocalAuthenticator.create_system_users = False │ │ │ │ - │ │ │ │ -## Delete any users from the database that do not pass validation │ │ │ │ -# See also: Authenticator.delete_invalid_users │ │ │ │ -# c.LocalAuthenticator.delete_invalid_users = False │ │ │ │ - │ │ │ │ -## Enable persisting auth_state (if available). │ │ │ │ -# See also: Authenticator.enable_auth_state │ │ │ │ -# c.LocalAuthenticator.enable_auth_state = False │ │ │ │ +# This is the default proxy implementation for running the nodejs proxy │ │ │ │ +# `configurable-http-proxy`. │ │ │ │ +# │ │ │ │ +# If the proxy should not be run as a subprocess of the Hub, (e.g. in a separate │ │ │ │ +# container), set:: │ │ │ │ +# │ │ │ │ +# c.ConfigurableHTTPProxy.should_start = False │ │ │ │ │ │ │ │ -## DEPRECATED: use allowed_groups │ │ │ │ -# Default: set() │ │ │ │ -# c.LocalAuthenticator.group_whitelist = set() │ │ │ │ +## The ip (or hostname) of the proxy's API endpoint │ │ │ │ +# Default: '' │ │ │ │ +# c.ConfigurableHTTPProxy.api_url = '' │ │ │ │ │ │ │ │ -## Let authenticator manage user groups │ │ │ │ -# See also: Authenticator.manage_groups │ │ │ │ -# c.LocalAuthenticator.manage_groups = False │ │ │ │ +## The Proxy auth token │ │ │ │ +# │ │ │ │ +# Loaded from the CONFIGPROXY_AUTH_TOKEN env variable by default. │ │ │ │ +# Default: '' │ │ │ │ +# c.ConfigurableHTTPProxy.auth_token = '' │ │ │ │ │ │ │ │ -## Let authenticator manage roles │ │ │ │ -# See also: Authenticator.manage_roles │ │ │ │ -# c.LocalAuthenticator.manage_roles = False │ │ │ │ +## Interval (in seconds) at which to check if the proxy is running. │ │ │ │ +# Default: 5 │ │ │ │ +# c.ConfigurableHTTPProxy.check_running_interval = 5 │ │ │ │ │ │ │ │ -## │ │ │ │ -# See also: Authenticator.otp_prompt │ │ │ │ -# c.LocalAuthenticator.otp_prompt = 'OTP:' │ │ │ │ +## The command to start the proxy │ │ │ │ +# Default: ['configurable-http-proxy'] │ │ │ │ +# c.ConfigurableHTTPProxy.command = ['configurable-http-proxy'] │ │ │ │ │ │ │ │ -## │ │ │ │ -# See also: Authenticator.post_auth_hook │ │ │ │ -# c.LocalAuthenticator.post_auth_hook = None │ │ │ │ +## The number of requests allowed to be concurrently outstanding to the proxy │ │ │ │ +# │ │ │ │ +# Limiting this number avoids potential timeout errors by sending too many │ │ │ │ +# requests to update the proxy at once │ │ │ │ +# Default: 10 │ │ │ │ +# c.ConfigurableHTTPProxy.concurrency = 10 │ │ │ │ │ │ │ │ -## Force refresh of auth prior to spawn. │ │ │ │ -# See also: Authenticator.refresh_pre_spawn │ │ │ │ -# c.LocalAuthenticator.refresh_pre_spawn = False │ │ │ │ +## Add debug-level logging to the Proxy. │ │ │ │ +# Default: False │ │ │ │ +# c.ConfigurableHTTPProxy.debug = False │ │ │ │ │ │ │ │ ## │ │ │ │ -# See also: Authenticator.request_otp │ │ │ │ -# c.LocalAuthenticator.request_otp = False │ │ │ │ - │ │ │ │ -## Reset managed roles to result of `load_managed_roles()` on startup. │ │ │ │ -# See also: Authenticator.reset_managed_roles_on_startup │ │ │ │ -# c.LocalAuthenticator.reset_managed_roles_on_startup = False │ │ │ │ - │ │ │ │ -## Dictionary of uids to use at user creation time. This helps ensure that users │ │ │ │ -# created from the database get the same uid each time they are created in │ │ │ │ -# temporary deployments or containers. │ │ │ │ -# Default: {} │ │ │ │ -# c.LocalAuthenticator.uids = {} │ │ │ │ +# See also: Proxy.extra_routes │ │ │ │ +# c.ConfigurableHTTPProxy.extra_routes = {} │ │ │ │ │ │ │ │ -## Dictionary mapping authenticator usernames to JupyterHub users. │ │ │ │ -# See also: Authenticator.username_map │ │ │ │ -# c.LocalAuthenticator.username_map = {} │ │ │ │ +## Proxy log level │ │ │ │ +# Choices: any of ['debug', 'info', 'warn', 'error'] (case-insensitive) │ │ │ │ +# Default: 'info' │ │ │ │ +# c.ConfigurableHTTPProxy.log_level = 'info' │ │ │ │ │ │ │ │ -## │ │ │ │ -# See also: Authenticator.username_pattern │ │ │ │ -# c.LocalAuthenticator.username_pattern = '' │ │ │ │ +## File in which to write the PID of the proxy process. │ │ │ │ +# Default: 'jupyterhub-proxy.pid' │ │ │ │ +# c.ConfigurableHTTPProxy.pid_file = 'jupyterhub-proxy.pid' │ │ │ │ │ │ │ │ -## Deprecated, use `Authenticator.allowed_users` │ │ │ │ -# See also: Authenticator.whitelist │ │ │ │ -# c.LocalAuthenticator.whitelist = set() │ │ │ │ +## Should the Hub start the proxy │ │ │ │ +# See also: Proxy.should_start │ │ │ │ +# c.ConfigurableHTTPProxy.should_start = True │ │ │ │ │ │ │ │ #------------------------------------------------------------------------------ │ │ │ │ -# PAMAuthenticator(LocalAuthenticator) configuration │ │ │ │ +# DummyAuthenticator(Authenticator) configuration │ │ │ │ #------------------------------------------------------------------------------ │ │ │ │ -## Authenticate local UNIX users with PAM │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: LocalAuthenticator.add_user_cmd │ │ │ │ -# c.PAMAuthenticator.add_user_cmd = [] │ │ │ │ - │ │ │ │ -## Authoritative list of user groups that determine admin access. Users not in │ │ │ │ -# these groups can still be granted admin status through admin_users. │ │ │ │ +## Dummy Authenticator for testing │ │ │ │ # │ │ │ │ -# allowed/blocked rules still apply. │ │ │ │ +# By default, any username + password is allowed If a non-empty password is set, │ │ │ │ +# any username will be allowed if it logs in with that password. │ │ │ │ # │ │ │ │ -# Note: As of JupyterHub 2.0, full admin rights should not be required, and more │ │ │ │ -# precise permissions can be managed via roles. │ │ │ │ -# Default: set() │ │ │ │ -# c.PAMAuthenticator.admin_groups = set() │ │ │ │ +# .. versionadded:: 1.0 │ │ │ │ +# │ │ │ │ +# .. versionadded:: 5.0 │ │ │ │ +# `allow_all` defaults to True, │ │ │ │ +# preserving default behavior. │ │ │ │ │ │ │ │ ## │ │ │ │ # See also: Authenticator.admin_users │ │ │ │ -# c.PAMAuthenticator.admin_users = set() │ │ │ │ +# c.DummyAuthenticator.admin_users = set() │ │ │ │ │ │ │ │ ## │ │ │ │ # See also: Authenticator.allow_all │ │ │ │ -# c.PAMAuthenticator.allow_all = False │ │ │ │ +# c.DummyAuthenticator.allow_all = False │ │ │ │ │ │ │ │ ## │ │ │ │ # See also: Authenticator.allow_existing_users │ │ │ │ -# c.PAMAuthenticator.allow_existing_users = False │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: LocalAuthenticator.allowed_groups │ │ │ │ -# c.PAMAuthenticator.allowed_groups = set() │ │ │ │ +# c.DummyAuthenticator.allow_existing_users = False │ │ │ │ │ │ │ │ ## │ │ │ │ # See also: Authenticator.allowed_users │ │ │ │ -# c.PAMAuthenticator.allowed_users = set() │ │ │ │ +# c.DummyAuthenticator.allowed_users = set() │ │ │ │ │ │ │ │ ## Is there any allow config? │ │ │ │ # See also: Authenticator.any_allow_config │ │ │ │ -# c.PAMAuthenticator.any_allow_config = False │ │ │ │ +# c.DummyAuthenticator.any_allow_config = False │ │ │ │ │ │ │ │ ## The max age (in seconds) of authentication info │ │ │ │ # See also: Authenticator.auth_refresh_age │ │ │ │ -# c.PAMAuthenticator.auth_refresh_age = 300 │ │ │ │ +# c.DummyAuthenticator.auth_refresh_age = 300 │ │ │ │ │ │ │ │ ## Automatically begin the login process │ │ │ │ # See also: Authenticator.auto_login │ │ │ │ -# c.PAMAuthenticator.auto_login = False │ │ │ │ +# c.DummyAuthenticator.auto_login = False │ │ │ │ │ │ │ │ ## │ │ │ │ # See also: Authenticator.auto_login_oauth2_authorize │ │ │ │ -# c.PAMAuthenticator.auto_login_oauth2_authorize = False │ │ │ │ +# c.DummyAuthenticator.auto_login_oauth2_authorize = False │ │ │ │ │ │ │ │ ## │ │ │ │ # See also: Authenticator.blocked_users │ │ │ │ -# c.PAMAuthenticator.blocked_users = set() │ │ │ │ - │ │ │ │ -## Whether to check the user's account status via PAM during authentication. │ │ │ │ -# │ │ │ │ -# The PAM account stack performs non-authentication based account management. It │ │ │ │ -# is typically used to restrict/permit access to a service and this step is │ │ │ │ -# needed to access the host's user access control. │ │ │ │ -# │ │ │ │ -# Disabling this can be dangerous as authenticated but unauthorized users may be │ │ │ │ -# granted access and, therefore, arbitrary execution on the system. │ │ │ │ -# Default: True │ │ │ │ -# c.PAMAuthenticator.check_account = True │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: LocalAuthenticator.create_system_users │ │ │ │ -# c.PAMAuthenticator.create_system_users = False │ │ │ │ +# c.DummyAuthenticator.blocked_users = set() │ │ │ │ │ │ │ │ ## Delete any users from the database that do not pass validation │ │ │ │ # See also: Authenticator.delete_invalid_users │ │ │ │ -# c.PAMAuthenticator.delete_invalid_users = False │ │ │ │ +# c.DummyAuthenticator.delete_invalid_users = False │ │ │ │ │ │ │ │ ## Enable persisting auth_state (if available). │ │ │ │ # See also: Authenticator.enable_auth_state │ │ │ │ -# c.PAMAuthenticator.enable_auth_state = False │ │ │ │ - │ │ │ │ -## The text encoding to use when communicating with PAM │ │ │ │ -# Default: 'utf8' │ │ │ │ -# c.PAMAuthenticator.encoding = 'utf8' │ │ │ │ - │ │ │ │ -## Number of executor threads. │ │ │ │ -# │ │ │ │ -# PAM auth requests happen in this thread, so it is mostly waiting for the pam │ │ │ │ -# stack. One thread is usually enough, unless your pam stack is doing something │ │ │ │ -# slow like network requests │ │ │ │ -# Default: 4 │ │ │ │ -# c.PAMAuthenticator.executor_threads = 4 │ │ │ │ - │ │ │ │ -## DEPRECATED: use allowed_groups │ │ │ │ -# See also: LocalAuthenticator.group_whitelist │ │ │ │ -# c.PAMAuthenticator.group_whitelist = set() │ │ │ │ +# c.DummyAuthenticator.enable_auth_state = False │ │ │ │ │ │ │ │ ## Let authenticator manage user groups │ │ │ │ # See also: Authenticator.manage_groups │ │ │ │ -# c.PAMAuthenticator.manage_groups = False │ │ │ │ +# c.DummyAuthenticator.manage_groups = False │ │ │ │ │ │ │ │ ## Let authenticator manage roles │ │ │ │ # See also: Authenticator.manage_roles │ │ │ │ -# c.PAMAuthenticator.manage_roles = False │ │ │ │ - │ │ │ │ -## Whether to open a new PAM session when spawners are started. │ │ │ │ -# │ │ │ │ -# This may trigger things like mounting shared filesystems, loading credentials, │ │ │ │ -# etc. depending on system configuration. │ │ │ │ -# │ │ │ │ -# The lifecycle of PAM sessions is not correct, so many PAM session │ │ │ │ -# configurations will not work. │ │ │ │ -# │ │ │ │ -# If any errors are encountered when opening/closing PAM sessions, this is │ │ │ │ -# automatically set to False. │ │ │ │ -# │ │ │ │ -# .. versionchanged:: 2.2 │ │ │ │ -# │ │ │ │ -# Due to longstanding problems in the session lifecycle, │ │ │ │ -# this is now disabled by default. │ │ │ │ -# You may opt-in to opening sessions by setting this to True. │ │ │ │ -# Default: False │ │ │ │ -# c.PAMAuthenticator.open_sessions = False │ │ │ │ +# c.DummyAuthenticator.manage_roles = False │ │ │ │ │ │ │ │ ## │ │ │ │ # See also: Authenticator.otp_prompt │ │ │ │ -# c.PAMAuthenticator.otp_prompt = 'OTP:' │ │ │ │ +# c.DummyAuthenticator.otp_prompt = 'OTP:' │ │ │ │ │ │ │ │ -## Round-trip the username via PAM lookups to make sure it is unique │ │ │ │ +## Set a global password for all users wanting to log in. │ │ │ │ # │ │ │ │ -# PAM can accept multiple usernames that map to the same user, for example │ │ │ │ -# DOMAIN\username in some cases. To prevent this, convert username into uid, │ │ │ │ -# then back to uid to normalize. │ │ │ │ -# Default: False │ │ │ │ -# c.PAMAuthenticator.pam_normalize_username = False │ │ │ │ +# This allows users with any username to log in with the same static password. │ │ │ │ +# Default: '' │ │ │ │ +# c.DummyAuthenticator.password = '' │ │ │ │ │ │ │ │ ## │ │ │ │ # See also: Authenticator.post_auth_hook │ │ │ │ -# c.PAMAuthenticator.post_auth_hook = None │ │ │ │ +# c.DummyAuthenticator.post_auth_hook = None │ │ │ │ │ │ │ │ ## Force refresh of auth prior to spawn. │ │ │ │ # See also: Authenticator.refresh_pre_spawn │ │ │ │ -# c.PAMAuthenticator.refresh_pre_spawn = False │ │ │ │ +# c.DummyAuthenticator.refresh_pre_spawn = False │ │ │ │ │ │ │ │ ## │ │ │ │ # See also: Authenticator.request_otp │ │ │ │ -# c.PAMAuthenticator.request_otp = False │ │ │ │ +# c.DummyAuthenticator.request_otp = False │ │ │ │ │ │ │ │ ## Reset managed roles to result of `load_managed_roles()` on startup. │ │ │ │ # See also: Authenticator.reset_managed_roles_on_startup │ │ │ │ -# c.PAMAuthenticator.reset_managed_roles_on_startup = False │ │ │ │ - │ │ │ │ -## The name of the PAM service to use for authentication │ │ │ │ -# Default: 'login' │ │ │ │ -# c.PAMAuthenticator.service = 'login' │ │ │ │ - │ │ │ │ -## │ │ │ │ -# See also: LocalAuthenticator.uids │ │ │ │ -# c.PAMAuthenticator.uids = {} │ │ │ │ +# c.DummyAuthenticator.reset_managed_roles_on_startup = False │ │ │ │ │ │ │ │ ## Dictionary mapping authenticator usernames to JupyterHub users. │ │ │ │ # See also: Authenticator.username_map │ │ │ │ -# c.PAMAuthenticator.username_map = {} │ │ │ │ +# c.DummyAuthenticator.username_map = {} │ │ │ │ │ │ │ │ ## │ │ │ │ # See also: Authenticator.username_pattern │ │ │ │ -# c.PAMAuthenticator.username_pattern = '' │ │ │ │ +# c.DummyAuthenticator.username_pattern = '' │ │ │ │ │ │ │ │ ## Deprecated, use `Authenticator.allowed_users` │ │ │ │ # See also: Authenticator.whitelist │ │ │ │ -# c.PAMAuthenticator.whitelist = set() │ │ │ │ +# c.DummyAuthenticator.whitelist = set()