diff --git a/src/7-to-8/major-changes/ui.rst b/src/7-to-8/major-changes/ui.rst index 616d1bc192..9542ee5b43 100644 --- a/src/7-to-8/major-changes/ui.rst +++ b/src/7-to-8/major-changes/ui.rst @@ -45,7 +45,11 @@ and as a multi user hub, ``cylc hub``. Both are dependent on `Cylc UI Server`_ i Launching the UI via the hub will require authentication. The default Authenticator uses PAM to authenticate system users with their username and password. -Going via the hub unlocks the :ref:`Authorization` feature. + +Going via the hub unlocks the ability to grant other users the permission +to view and interact with workflows running under your account. +Site administrators will need to configure this, for more information +see :ref:`cylc.uiserver.multi-user`. .. figure:: ../../img/hub.png :figwidth: 80% diff --git a/src/conf.py b/src/conf.py index a01b50ffb5..39ce482212 100644 --- a/src/conf.py +++ b/src/conf.py @@ -110,6 +110,8 @@ autosummary_imported_members = False # Mapping to other Sphinx projects we want to import references from. +# NOTE: To search available references, use: +# $ python -m sphinx.ext.intersphinx /objects.inv | less intersphinx_mapping = { 'rose': ( 'http://metomi.github.io/rose/2.1.0/html', None @@ -119,6 +121,9 @@ ), 'jupyter_server': ( 'https://jupyter-server.readthedocs.io/en/latest/', None + ), + 'jupyter_hub': ( + 'https://jupyterhub.readthedocs.io/en/stable/', None ) } diff --git a/src/dictionaries/words b/src/dictionaries/words index d390f1c02c..13f17b63e5 100644 --- a/src/dictionaries/words +++ b/src/dictionaries/words @@ -5,6 +5,7 @@ arg args auth authenticator +authoriser backticks baz boolean @@ -185,6 +186,7 @@ timeouts timestep timezone timezones +uiserver unpaused unpausing untracked diff --git a/src/reference/architecture/ui-server.rst b/src/reference/architecture/ui-server.rst index 4ebe6ca22f..0af147b37d 100644 --- a/src/reference/architecture/ui-server.rst +++ b/src/reference/architecture/ui-server.rst @@ -92,8 +92,14 @@ spawns UI Servers on behalf of users and provides each with a fixed URL Users can access each other's UI Servers providing they have been granted permission. -Authorization is performed by Cylc within the `Cylc UI Server`_, see -:ref:`cylc authorization`. +*Authentication* is provided by either `Jupyter Server`_ or `Jupyter Hub`_. + +*Authorization* in the `Cylc UI Server`_ is provided by Cylc. In +multi-user mode this allows users to connect to each other's UI Servers for +monitoring or control purposes. + +For more information on security and configuration see +:ref:`cylc.uiserver.multi-user`. .. _Jupyter Hub technical overview: https://jupyterhub.readthedocs.io/en/stable/reference/technical-overview.html @@ -109,24 +115,3 @@ For information on the architecture of `Jupyter Hub`_ and the .. image:: img/gui-arch-multi-user.svg :width: 100% - - -.. _cylc authorization: - -Authorization -------------- - -*Authentication* is provided by either `Jupyter Server`_ or `Jupyter Hub`_. - -*Authorization* in the `Cylc UI Server`_ is provided by Cylc. In -multi-user mode this allows users to connect to each others UI Servers for -monitoring or control purposes. - -See also :ref:`Authorization`. - -.. note:: - - This authorization only applies to the ``/cylc`` endpoints managed by the - Cylc extension. Other `Jupyter Server`_ extensions such as `Jupyter Lab`_ - do not share this authorization and will not be accessible to other users - (unless they can be configured to allow this). diff --git a/src/reference/changes.rst b/src/reference/changes.rst index 3c1fcb618c..120410422d 100644 --- a/src/reference/changes.rst +++ b/src/reference/changes.rst @@ -20,6 +20,36 @@ For more detail see the component changelogs: * `metomi-rose-changelog`_ * `metomi-isodatetime-changelog`_ + +---------- + +Cylc 8.3.0 +---------- + +.. admonition:: Cylc Components + :class: hint + + TODO + +.. + Uncomment this before 8.3.0 release + + :cylc-flow: `8.3 `__ + :cylc-uiserver: `1.4 `__ + :cylc-rose: `1.4 `__ + + +Upgrade To The Latest Jupyter Releases +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The Cylc UI Server has been updated to work with the latest releases of +`Jupyter Server`_ and `Jupyter Hub`_. + +If you are utilising Cylc's multi-user functionality then your configuration +will require some changes to work with these releases. + +See :ref:`cylc.uiserver.multi-user` for more details + ---------- Cylc 8.2.0 diff --git a/src/user-guide/sharing-access-to-workflows.rst b/src/user-guide/sharing-access-to-workflows.rst index 4e74e5f28b..637d2e70c3 100644 --- a/src/user-guide/sharing-access-to-workflows.rst +++ b/src/user-guide/sharing-access-to-workflows.rst @@ -1,148 +1,266 @@ -.. _Authorization: +.. _cylc.uiserver.multi-user: Authorizing Others to Access Your Workflows =========================================== -The Cylc UI Server supports multi user access. You can grant control of your -workflows to other users, by adding or removing privileges on a Cylc operation -basis. This requires site level configuration, with individual users being able -to set authorization settings, within the bounds set by the site. +For multi-user setups, the Cylc web GUI can be deployed as part of a +`Jupyter Hub`_ setup where a central service spawns servers on behalf of users. -Sites can set default access rights for users, for more information, see -:ref:`site_configuration`. +The Cylc UI Server can be configured to allow specified users to monitor and +optionally control workflows running under other user accounts. -Note, if this feature is not configured, the default is no multi user access, -only the workflow owner will be able to interact with it. +This has many use cases including: -If you grant access to another user, this access will apply to all of your -workflows. +* Collaborative research setups where multiple users need to access the same + workflow. +* Production systems where different levels of support may have different + levels of access. +* Support where administrators may require access to users workflows. -Granting Access ---------------- +A multi-user Cylc setup consists of three components: -There are three methods of identifying a user to grant access to: +1. `Jupyter Hub`_ +2. `Jupyter Server`_ +3. `Cylc UI Server`_ -- ``*`` character, to indicate any authenticated user, -- using the ``group:`` prefix to indicate a system group. E.g. - ``group:groupname``, will assign permissions to all members of the system - group named ``groupname``. For more information, see :ref:`group_support`. -- ``username`` to indicate a specific user. +And may additionally include other Jupyter Server extensions such as +`Jupyter Lab`_ to provide a full interactive virtual workstation in the +browser. +In order to allow access to other users servers, to permit the monitoring and +optionally control of other users workflows, each of these three components +must be configured: -Using glob (``*``) to pattern match usernames and group names is not currently -supported. +1. `Jupyter Hub`_ must be configured to allow connections to other users servers. +2. The `Jupyter Server`_ authorisation policy must be set. +3. Cylc must be configured with user permissions. -Permissions are additive. If the user appears elsewhere in configuration, for -example as a member of a system group, the permission level is taken as the -greatest possible. +This configuration can all be performed in the same Jupyter / Cylc UI Server +configuration file. See :ref:`UI_Server_config` for more details. -However, negations take precedence. +.. rubric:: Quick Example: -Note, defaults in site config only apply if a user does not appear in the -``c.CylcUIServer.user_authorization``. +.. code-block:: python -Methods of Assigning Permissions --------------------------------- -Assigning permissions can be done in two ways: + # /etc/cylc/uiserver/jupyter_config.py - - using individual Cylc operations, e.g. ``play``, ``pause`` - - using predefined access groups: ``READ``, ``CONTROL``, ``ALL``. + # 1. Jupyter Hub + # Allow all authenticated users to access, start and stop + # each other's servers + c.JupyterHub.load_roles = [ + { + "name": "user", + "scopes": ["self", "access:servers", "servers"], + } + ] -Using both methods is supported, e.g ["READ", "stop", "pause"] -Individual Operations -^^^^^^^^^^^^^^^^^^^^^ -To assign users permissions, you can list the operations you wish to grant + # 2. Jupyter Server + # Set a safe authorisation policy for multi-user setups + # Note: This is ONLY necessary if you are deploying the Cylc UI Server + # using commands other than `cylc hub` and `cylc hubapp`, + # otherwise, it is the default. + from cylc.uiserver.authorise import CylcAuthorizer + c.ServerApp.authorizer_class = CylcAuthorizer -.. code-block:: python + # 3. Cylc + # Delegate permissions to users c.CylcUIServer.user_authorization = { - "user1": ["read", "pause", "play"] + # provide all authenticated users with read-only access to each other's + # servers + "*": ["READ"], } -Provided you have permission (via the site config file) to grant ``user1`` -these permissions, this will result in ``user1`` being able to see your -workflows (from the ``read`` operation), and ``pause`` and ``play`` your workflows. +The rest of this document takes you through each of these configurations, some +of the key options and how they relate to their respective systems. + + +.. _jupyterhub.authorization: +Jupyter Hub Authorisation +------------------------- -To remove permissions prepend the operation with a ``!``. -For example, +By default, `Jupyter Hub`_ only allows users to access their own servers. + +In order to allow access to other users' servers, two scopes must be configured: + +``access:servers`` + Permits us to connect to another user's server. +``servers`` + Permits us to start another user's server. + +This is done using the +:py:attr:`c.JupyterHub.load_roles ` +configuration. +For more information see the +:ref:`JupyterHub scopes reference `. + +Example: .. code-block:: python + # /etc/cylc/uiserver/jupyter_config.py + + c.JupyterHub.load_roles = [ + { + # allow all authenticated users to access, start and stop + # each other's servers + "name": "user", + "scopes": ["self", "access:servers", "servers"], + } + ] + + +.. _jupyterserver.authorization: + +Jupyter Server Authorisation +---------------------------- + +.. tip:: + + You can skip this section if you are starting Jupyter Hub using ``cylc hub`` + command and have not overridden the + :py:attr:`c.JupyterHub.spawner_class ` + configuration (so are spawning the ``cylc hubapp`` command). + +.. autoclass:: cylc.uiserver.authorise.CylcAuthorizer + + +.. _cylc.uiserver.user_authorization: + +Cylc User Authorisation +----------------------- + +Cylc Authorisation is configurable on a per-user and per-command basis but +not on a per-workflow basis. + +By default users can only see and interact with their own workflows. + +Sites can restrict the permissions that users are allowed to grant each +other and can configure default permissions (see :ref:`site_configuration`). + +Authorization is configured by these two configurations: + +* :py:attr:`c.CylcUIServer.user_authorization + ` (user configuration) +* :py:attr:`c.CylcUIServer.site_authorization + ` (site configuration) + +.. rubric:: Example: + +.. code-block:: python + + # ~/.cylc/uiserver/jupyter_config.py + c.CylcUIServer.user_authorization = { - "group:groupA": ["read", "play", "stop"], - "user2": ["!stop"] + # : [, ...], + + # allow "user1" to monitor my workflows + "user1": ["READ"], + + # allow "user2" to monitor and trigger tasks in my workflows + "user2": ["READ", "Trigger"], } -Providing your site configuration permits you to grant this access, -this configuration, for ``user2`` (who is a member of system group ``groupA``), -would result in them having ``read`` and ``play`` access. Permission to stop your -workflows has been removed so this action will be forbidden. -Access Groups -^^^^^^^^^^^^^ -For convenience, cylc operations available in the UI have been bundled into -access groups. These should be capitalized to distinguish from cylc operations. - -We currently support ``READ``, ``CONTROL`` and ``ALL`` and to remove permissions -to operations in these groups, use ``!READ``, ``!CONTROL``, ``!ALL``. - - -.. csv-table:: Access Group Mappings - :header: "Operation", "READ", "CONTROL", "ALL" - - "Broadcast", , , "X" - "Ext-trigger",, "X", "X" - "Hold",, "X", "X" - "Kill",, "X", "X" - "Message",, "X", "X" - "Pause",, "X", "X" - "Play",, "X", "X" - "Poll",, "X", "X" - "Read","X", , "X" - "Release",, "X", "X" - "ReleaseHoldPoint",, "X", "X" - "Reload",, "X", "X" - "Remove",, "X", "X" - "Resume",, "X", "X" - "SetGraphWindowExtent",, "X", "X" - "SetHoldPoint",, "X", "X" - "SetOutputs",, "X", "X" - "SetVerbosity",, "X", "X" - "Stop",, "X", "X" - "Trigger",, "X", "X" +Users +^^^^^ +There are three methods of identifying a user to grant access to: + +```` + Configures permissions for a single user. +``group:`` + Configures a user group. For more information, see :ref:`group_support`. +``*`` + Configures permissions for any authenticated user (see + :ref:`Jupyter Hub authenticators reference ` + for details). .. note:: - The ``READ`` access group is shorthand for all read-only operations. At present, - this is solely the ``read`` operation, which grants access to GraphQL queries and - subscriptions, and enables users to see the workflows in the UI. In future - the ``READ`` access group may be extended. + Using glob patterns to match user and group names is + not currently supported. + + +Permissions +^^^^^^^^^^^ + +.. TODO: autogenerate this permission list + https://github.com/cylc/cylc-uiserver/issues/466 + +Permissions can be granted for each Cylc command individually. For convenience, +commands are arranged into groups to avoid having to list them individually: + +``READ`` (i.e. read-only access) + A user with read permissions may view workflows, monitor tasks states and + open log files, but they cannot interact with the workflows. + + * ``Read`` +``CONTROL`` (e.g. start & stop workflows) + A user with control permissions may issue commands to interact with workflows + and can start/stop workflows but cannot redefine the workflow configuration + itself (without direct filesystem access). + + * ``Clean`` + * ``Ext-trigger`` + * ``Hold`` + * ``Kill`` + * ``Message`` + * ``Pause`` + * ``Play`` + * ``Poll`` + * ``Release`` + * ``ReleaseHoldPoint`` + * ``Reload`` + * ``Remove`` + * ``Resume`` + * ``SetGraphWindowExtent`` + * ``SetHoldPoint`` + * ``SetOutputs`` + * ``SetVerbosity`` + * ``Stop`` + * ``Trigger`` +``ALL`` (i.e. full control) + A user with all permissions may alter task configuration so may inject + arbitrary code into the workflow. + + * ``Broadcast`` .. note:: - Granting CONTROL access does not automatically grant READ access. + With the exception of ``Read`` all of the above permissions map onto the + Cylc GraphQL mutations which themselves map onto the command line. + + E.G. the ``Play`` permission maps onto ``mutation play`` in the GraphQL + schema and ``cylc play`` on the command line. + + To find out more about a command, see the GraphQL or CLI documentation. + +By default, users have full permissions (``READ``, ``CONTROL`` and ``ALL``) for their own workflows and no +permissions for other users' workflows. -.. _user_configuration: +Permissions are additive, so for example, granting ``READ`` and ``CONTROL`` +would provide all of the permissions from those two groups. -User Authorization Configuration --------------------------------- -``c.CylcUIServer.user_authorization``, which is loaded from -``~/.cylc/uiserver/jupyter_config.py``, contains your preferences for granting access -to other users. This configuration should be entered as a Python -dictionary. If a user does not appear in your user config, the default site -access will apply. -You are only permitted to grant access, within the bounds set at site level. +The ``!`` character can be used to subtract permissions, e.g. delegating +``CONTROL`` and ``!Stop`` would provide all control permissions except stop. + +.. note:: + + Granting access to a group does not automatically grant access to lower + groups e.g. granting ``CONTROL`` access does not automatically grant + ``READ`` access. -Example User Configuration -^^^^^^^^^^^^^^^^^^^^^^^^^^ -An example user configuration: +Examples +^^^^^^^^ .. code-block:: python + # ~/.cylc/uiserver/jupyter_config.py + c.CylcUIServer.user_authorization = { "*": ["READ"], "group:groupA": ["CONTROL"], @@ -153,63 +271,98 @@ An example user configuration: In this scenario: - ``"*"`` represents any authenticated user. They have permission to view all - workflows, and view them on the GUI. - + workflows on the GUI. - ``"group:groupA"`` applies ``CONTROL`` permissions to any member of system ``groupA``. - Note that, since permissions are additive, these users will gain ``READ`` access + Note that, since permissions are inherited, these users will gain ``READ`` access from the ``"*":["READ"]`` assignment. - - ``"user1"`` will have permission to view workflows, ``pause`` but not ``play`` workflows, even if ``user1`` is a member of the system ``groupA``. This is due to negations taking precedence over additions. - - ``"user2"`` is not permitted to view workflows, or perform any operations. + .. _site_configuration: -Site Authorization Configuration --------------------------------- -The site_authorization configuration allows sites to configure sensible defaults -and limits for the permissions users can delegate. +Cylc Site Configuration +----------------------- + +The :py:attr:`c.CylcUIServer.site_authorization +` configuration allows sites +to configure sensible defaults and limits for the permissions users can +grant. + +It takes the form: + +.. code-block:: python + + { + "": { + "": { + "default": [], + "limit": [] + } + } + } + +Where ```` is the username of the account that is running a server and +```` is the username of an account trying to connect to it. + +Sites can set both limits and defaults for users: -Note that as the UI Server runs as the workflow owner, they have full control -over it and in theory may bypass these restrictions in a variety of ways. As an -extreme example, a workflow owner could pass their account credentials to -another person, and that cannot be prevented by technical means. However, a -workflow owner cannot unilaterally gain access to any other user's account or -workflows by configuring their own UI Server. +``limit`` + Determines the maximum access users can grant to their workflows. +``default`` + Sets a default access level, which applies if the user does not appear in + the user_authorization configuration (via explicit user name or group). -``c.CylcUIServer.site_authorization``, which is loaded from -``/etc/cylc/uiserver/jupyter_config.py``, or, alternatively, the environment variable -``CYLC_SITE_CONF_PATH``, contains these site default and limit settings for -users. This configuration should be entered as a Python dictionary. + Note, these defaults apply only if a user does not appear in + :py:attr:`c.CylcUIServer.user_authorization + `. +* If a limit is not set but a default is, then the limit is the default. +* If a default is not set but a limit is, then the default is no access. -Defaults and Limits -^^^^^^^^^^^^^^^^^^^ -Sites set both limits and defaults for users. +.. note:: + + As the UI Server runs as the workflow owner, the owner has full control over + it and in theory may bypass these restrictions in a variety of ways. As an + extreme example, a workflow owner could pass their account credentials to + another person. This cannot be prevented by technical means. However, a + workflow owner cannot unilaterally gain access to any other user's account + or workflows by configuring their own UI Server. -- ``limit`` determines the maximum access users can grant to their workflows. +.. note:: -- ``default`` sets a default access level, which applies if the user does - not appear in the user_authorization configuration (via explicit user name or group). + Changes to the Cylc authorization configuration will take effect when the + Cylc UI Server is restarted. -Missing Configurations in Site Authorization -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -For site configuration: -* if a limit is not set but a default is, then the limit is the default. -* if a default is not set but a limit is, then the default is no access. +.. _group_support: + +Group Support +^^^^^^^^^^^^^ + +Unix-like systems support user groups. Cylc authorization supports granting +access by membership of these system groups. You can indicate a system group +by using the ``group:`` indicator. + +System groups are found by +:py:mod:`get_groups` + +.. autofunction:: cylc.uiserver.authorise.get_groups Example Site Authorization Configuration ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Whilst most site configurations will be simpler than the example below, this example provides an indication of the combinations available. .. code-block:: python + # /etc/cylc/uiserver/jupyter_config.py + c.CylcUIServer.site_authorization = { "*": { # For all ui-server owners, "*": { # Any authenticated user @@ -253,31 +406,9 @@ example provides an indication of the combinations available. } -.. _group_support: - -Group Support -^^^^^^^^^^^^^ -Unix-like systems support grouping users. Cylc authorization supports granting -access by membership of these system groups. You can indicate a system group -by using the ``group:`` indicator. - -System groups are found by - :py:mod:`get_groups` - - .. autofunction:: cylc.uiserver.authorise.get_groups - - -Changing Access Rights -^^^^^^^^^^^^^^^^^^^^^^ -Changing authorization permissions in your ``jupyter_config.py`` will require the -UI Server to be restarted before any changes are applied. - Interacting with Others' Workflows ---------------------------------- -The authorization system in Cylc 8 is complete, although expect access to other -users' workflows via the UI to be further developed in future. - .. spelling:word-list:: userA @@ -294,18 +425,14 @@ have the correct permissions, you will see userB's workflows for interaction. Operations that are not authorized will appear greyed out on the UI. + Troubleshooting Authorization ----------------------------- If authorization is not performing as expected, check - you are permitted by the site configuration to give away access. - - you have provided ``read`` permissions, which enables the user to see your workflows. - - check the spelling in your configuration. The correct spelling is ``c.CylcUIServer.user_authorization`` - -- the server has been started by the user of the workflows you are trying to - access. Users currently can only spawn their own UI Servers.