.. _globus_auth_setup:
Set Up an Action Provider in Globus Auth
========================================
The Action Provider Interface makes use of and is bound closely with
authentication via the `Globus Auth
`_ system. To
authenticate RESTful requests using Globus Auth, a service must register as a
"resource server". This is a multi-step process involving use of both the Globus
Auth developer portal and the Globus Auth API for configuring various access
control states. To help with this process, we provide a step-by-step guide to
using Globus Auth for this purpose
.. note::
In the examples below, we will use the command line tool ``curl`` to
perform the HTTP operations as it is widely available. We also use the
command line tool ``jq`` to format the ``curl`` command's json responses.
However, other tools and clients exist for interacting with REST and HTTP
services, so you may need to translate the ``curl`` and ``jq`` commands to
your preferred tools.
Step 1: Register a new App
^^^^^^^^^^^^^^^^^^^^^^^^^^
Register a new App on ``_ using a browser.
Once logged in, perform the following steps
- Select "Add another project"
- | Provide a name, contact email and select which of your own Globus Auth
linked identities are permitted to administer the project. You will be
required to login with this identity in future interactions with the Globus
Developer Portal to manipulate the resource server.
- After filling in your new Project's details, select "Create Project"
- | Find your new, empty project, and select the "Add" drop down and then click
"Add new app"
- | Provide a name for the specific app within the project. This will be a
common name displayed to users when they make use of the Action Provider.
"Redirects" is not used, but a value must be provided. You can use a
URL associated with your service or a placeholder value like ``"https://localhost"``.
- | When creating a resource server, the other fields on the app creation page
are not used. On this menu, "Scopes" is not relevant and make no
difference, so this field should be left blank. The "Privacy Policy" and
"Terms and Conditions" may be displayed to users making use of your action
provider, but they are not required.
- Select "Create app"
- You will be redirected to the "Apps and Services" page. Scroll to your
Project, then to the newly created App. Make note of the "Client ID" in the
expanded description of your app. This value will be used elsewhere in the
creation of the service and is often referenced as ``client_id``.
- In the section "Client Secrets" click "Generate New Client Secret"
- | Provide a Description which is meaningful to you. It will not be
displayed to other users.
- Click "Generate Secret".
- | Make note of the generated secret. Like the ``client_id`` this will be
used later in development. Be sure **not to lose it** as it can only be
displayed once. However, new client secrets can be created and old ones
deleted at any time should the need for a replacement secret arise.
- | Set the client_id and client_secret on your command line to follow
along with the rest of this guide.
.. code-block:: BASH
export CLIENT_ID=
export CLIENT_SECRET=
Step 2: Use the Globus Auth API to introspect your Action Provider Resource Server
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | Introspect your Globus Auth client to see the same settings you setup in
the developer portal. Notice we exported the ```` and
```` values generated during your registration on the Globus
Developer Portal into environment variables.
.. code-block:: BASH
curl -s --user $CLIENT_ID:$CLIENT_SECRET \
https://auth.globus.org/v2/api/clients/$CLIENT_ID | jq
- | A successful return from this command is a JSON representation of the
Globus Auth client similar to:
.. code-block:: JSON
{
"client": {
"scopes": [],
"redirect_uris": [
"https://localhost"
],
"name": "My Action Provider",
"links": {
"privacy_policy": null,
"terms_and_conditions": null
},
"grant_types": [
"authorization_code",
"client_credentials",
"refresh_token",
"urn:globus:auth:grant_type:dependent_token"
],
"fqdns": [],
"visibility": "private",
"project": "a47b9014-9250-4e21-9de5-b4aac81d464b",
"required_idp": null,
"preselect_idp": null,
"id": "8e98ba5a-21a9-4bef-ab6a-0fcdbed36405",
"public_client": false,
"parent_client": null
}
}
- | Of note is the ``scopes`` field. ``scopes`` are created to identify
operations on the Action Provider. Typically, an Action Provide defines just
one scope and it is provided to users in the Action Provider's introspection
(``GET /``) information in the field ``globus_auth_scope``. In the next
section, we demonstrate how to create a ``scope``.
Step 3. Create your Action Provider's Scope
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- | Creation of a scope is required as the scope will be used in authenticating
REST calls on the Action Provider.
- | Start by creating a "scope definition" JSON document in the
following format replacing the ``name``, ``description`` and optionally
the ``scope_suffix``.
.. code-block:: JSON
{
"scope": {
"name": "Action Provider Operations",
"description": "All Operations on My Action Provider",
"scope_suffix": "action_all",
"dependent_scopes": [
{
"optional": false,
"requires_refresh_token": true,
"scope": "73320ffe-4cb4-4b25-a0a3-83d53d59ce4f"
}
],
"advertised": true,
"allow_refresh_tokens": true
}
}
- | The ``name`` and ``description`` fields are purely
informative and will be presented to other users who use the Globus Auth API
to lookup the scope. The ``scope_suffix`` will be placed at the end of the
generated "scope string" which is a URL identifier for the scope. It
provides the context for the operations this scope covers among all
operations your service provides. For Action Providers, we commonly use
``action_all`` to indicate all operations defined by the Action Provider
API, but any string is acceptable.
- | The ``advertised`` property indicates whether the scope will be
visible to all users who do scope look ups on Globus Auth. You may select
either ``true`` or ``false`` for this depending on your own policy.
``allow_refresh_tokens`` should generally be set to ``true``, indicating
that a client of the Action Provider who has authenticated the user via
Globus Auth is a allowed to refresh that authentication without further
interactions from the user. Especially in the case where an Action may be
long running and is monitored by an automated system like Globus Flows, it
is important that token refresh is permitted.
- | ``dependent_scopes`` define scopes of other Globus Auth resource
servers that your Action Provider will invoke to perform its work. For
example, if your Action Provider uses Globus Transfer to first move some
data to compute upon, the scope for the Globus Transfer service would be
placed in the ``dependent_scopes`` list. In the most common case, as
shown in the example, the scope for the `Globus Groups API
`_ (with UUID
``73320ffe-4cb4-4b25-a0a3-83d53d59ce4f``) should be listed. This allows
your Action Provider to determine what groups a user calling the
provider belongs to and can therefore enforce policies, such as
``runnable_by`` or ``monitor_by`` based on group membership. If this
scope is not listed as a dependent scope, the Action Provider Tools
library will not be able to, and will therefore not attempt to, retrieve
a user's groups and so no policies based on Groups may be used. We
encourage you to consult the `Globus Auth Documentation
`_ for more information on creation
and management of Scopes for more advanced scenarios such as other
dependent Globus Auth based services such as Globus Transfer.
.. note::
Scopes supplied in the dependent_scopes array must be identified by
their UUID. The snippet below demonstrates how to look up a scope's UUID
based on its uniquely idenfitfying FQDN
.. code-block:: BASH
# Target FQDN is https://auth.globus.org/scopes/actions.globus.org/transfer/transfer
export SCOPE_STRING=https://auth.globus.org/scopes/actions.globus.org/transfer/transfer
curl -s -u "$CLIENT_ID:$CLIENT_SECRET" \
"https://auth.globus.org/v2/api/scopes?scope_strings=$SCOPE_STRING" | jq ".scopes[0].id"
- | With the scope creation JSON document complete, use the following REST
interaction to create the scope in Globus Auth via the ``curl`` command.
.. code-block:: BASH
curl -s --user "$CLIENT_ID:$CLIENT_SECRET" -H \
'Content-Type: application/json' \
-XPOST https://auth.globus.org/v2/api/clients/$CLIENT_ID/scopes \
-d '' | jq
- | This command should return the definition of the new scope matching the
values provided in your scope creation document. As an example:
.. note::
The returned value is an *array* of scopes. That is, more than one scope
definition may be generated from the single scope creation request. This
happens in the uncommon case where an FQDN has been registered for your
``client_id`` (refer to the `Globus Auth Documentation
`_ for information on FQDN
registration if you desire it, though it is not recommended). In this
case, a similar scope definition will also be generated, but the
``scope_string`` will contain the FQDN value(s). The ``scope_string``
values may be used interchangeably both by users requesting
authentication to the Action Provider and in the ``globus_auth_scope``
value of the Action Provider Description.
.. code-block:: JSON
{
"scopes": [
{
"dependent_scopes": [
{
"optional": false,
"requires_refresh_token": true,
"scope": "73320ffe-4cb4-4b25-a0a3-83d53d59ce4f"
}
],
"description": "",
"allows_refresh_token": true,
"client": "",
"advertised": true,
"scope_string": "https://auth.globus.org/scopes//action_all",
"id": "",
"name": ""
}
]
}
- | The returned ``scope_string``, which always takes the form of a URL, will be
the value exposed to users who wish to authenticate with Globus Auth to use
your Action Provider. It will be part of the Action Provider description
document, returned on the Action Provider Introspection operation (``GET
/``) with the key ``globus_auth_scope``.
- | Verify that the created scope(s) are correctly associated with the Action
Provider:
.. code-block:: BASH
curl -s --user $CLIENT_ID:$CLIENT_SECRET \
https://auth.globus.org/v2/api/clients/$CLIENT_ID | jq
- | Once your app and its scope(s) have been created and verified, remove your
credentials from your command line environment. Be sure to take note of the
client ID and its associated client secret for use in other places in the toolkit.
.. code-block:: BASH
unset CLIENT_ID CLIENT_SECRET
Next Steps
^^^^^^^^^^
Once you have obtained your own CLIENT_ID and created a CLIENT_SECRET and
SCOPE, you have all the pieces required for creating an Action Provider.
For information on installing the toolkit read the :doc:`installation
page`.
For information on this toolkit's components, read the :doc:`toolkit
documentation`.
To see a few sample Action Provider implementations head over to the
:doc:`examples page`.