-
Notifications
You must be signed in to change notification settings - Fork 44
Add documentation on using ClientApp #1363
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
sirosen
merged 7 commits into
globus:main
from
sirosen:document-client-credentials-usage
Jan 22, 2026
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
09997af
Add documentation on using ClientApp
sirosen 5657458
Apply suggestions from code review
sirosen 1d2881f
Rename the 'Service Accounts' user guide section
sirosen a75751c
Add disambiguation to Service Accounts doc
sirosen 371a20f
Introduce 'Understanding Service Accounts' doc
sirosen 7f1b9fe
Update docs/user_guide/usage_patterns/service_accounts/understanding_…
sirosen 92e0fb9
Add 'conflicts' section to Service Accounts doc
sirosen File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,3 +29,4 @@ transfers. | |
|
|
||
| data_transfer/index | ||
| sessions_and_consents/index | ||
| service_accounts/index | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| .. _userguide_service_accounts: | ||
|
|
||
| Service Accounts | ||
| ================ | ||
|
|
||
| "Service Accounts" or "Client Identities" (the terms are synonymous) are | ||
| automated users which authenticate with Globus via client credentials. | ||
| Using this type of credential allows for automated usage of Globus services | ||
| which does not rely on user interaction or login flows. | ||
|
|
||
| .. toctree:: | ||
| :caption: Using Service Accounts with the SDK | ||
| :maxdepth: 1 | ||
|
|
||
| understanding_service_accounts | ||
| registering_a_service_account | ||
| using_client_app/index |
80 changes: 80 additions & 0 deletions
80
docs/user_guide/usage_patterns/service_accounts/registering_a_service_account.rst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,80 @@ | ||
| .. _userguide_register_service_account: | ||
|
|
||
| Registering a Service Account | ||
| ============================= | ||
|
|
||
| In order to be used as a Service Account or "Client Identity", a client must | ||
| be registered in Globus Auth under the correct type. | ||
|
|
||
| This is similar to the | ||
| :ref:`getting started documentation on registering an app <tutorial_register_app>`, | ||
| but using some different settings. | ||
|
|
||
| Creating the Client | ||
| ------------------- | ||
|
|
||
| The following steps will walk you through how to register a client for use as a | ||
| service account. | ||
| One topic not covered here is how to securely store and manage your secrets -- | ||
| the guidance below will simply say "save", and it is the user's responsibility | ||
| to decide how to save and secure these credentials. | ||
|
|
||
| 1. Navigate to the `Developer Site <https://app.globus.org/settings/developers>`_ | ||
|
|
||
| 2. Select "Register a service account or application credential for automation" | ||
|
|
||
| 3. Create or Select a Project | ||
|
|
||
| * A project is a collection of apps with a shared list of administrators. | ||
| * If you don't own any projects, you will automatically be prompted to create one. | ||
| * If you do, you will be prompted to either select an existing or create a new one. | ||
|
|
||
| 4. Creating or selecting a project will prompt you for another login, sign in with an | ||
| account that administers your project. | ||
|
|
||
| 5. Give your App a name. This will appear as the identity's "name" where a | ||
| user's full name might appear. | ||
|
|
||
| 6. Click "Register App". This will create your app and take you to a page | ||
| describing it. | ||
|
|
||
| 7. Copy the "Client UUID" and save it -- this is your ``client_id`` in the | ||
| Python SDK's terms. | ||
|
|
||
| 8. Click "Add Client Secret", fill in the label, and save the secret -- this is | ||
| your ``client_secret`` in the Python SDK's terms. | ||
|
|
||
|
|
||
| Saving and Retrieving Client IDs and Secrets | ||
| -------------------------------------------- | ||
|
|
||
| The Globus SDK does not offer special capabilities for storage and retrieval of | ||
| client IDs and client secrets. | ||
|
|
||
| In examples in SDK documentation, you will see the client ID and secret written | ||
| as hardcoded constants, e.g. | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| import globus_sdk | ||
|
|
||
| CLIENT_ID = "YOUR ID HERE" | ||
| CLIENT_SECRET = "YOUR SECRET HERE" | ||
|
|
||
| client = globus_sdk.ConfidentialAppAuthClient(CLIENT_ID, CLIENT_SECRET) | ||
|
|
||
| You can replace those variables with sources of your choice. | ||
| For example, you could make them environment variables: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| import os | ||
|
|
||
| CLIENT_ID = os.getenv("CLIENT_ID") | ||
| CLIENT_SECRET = os.getenv("CLIENT_SECRET") | ||
|
|
||
| if not (CLIENT_ID and CLIENT_SECRET): | ||
| raise RuntimeError("CLIENT_ID and CLIENT_SECRET must both be set.") | ||
|
|
||
| Selecting an appropriate storage and retrieval mechanism for client credentials | ||
| is considered a user responsibility by the SDK. |
126 changes: 126 additions & 0 deletions
126
docs/user_guide/usage_patterns/service_accounts/understanding_service_accounts.rst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,126 @@ | ||
| .. _userguide_understanding_service_accounts: | ||
|
|
||
| Understanding Service Accounts | ||
| ============================== | ||
|
|
||
| Some clients registered in Globus may operate as independent "service accounts", | ||
| distinct actors with their own identities. | ||
| These are also referred to as "client identities" because the actor in question | ||
| is the client itself. | ||
| Service accounts are useful for a wide range of automation tasks, in which users | ||
| want to leverage Globus APIs, but without handling login flows and user | ||
| credentials. | ||
|
|
||
| Service Accounts are Clients | ||
| ---------------------------- | ||
|
|
||
| To create a service account, users must register a new Globus Auth client as | ||
| a Service Account, capable of performing a *client credentials grant* to get | ||
| its tokens. | ||
| Once it is so registered, such a client will have an ID and secret, which can be | ||
| passed into interfaces in the SDK. | ||
|
|
||
| The client credentials (ID and secret) are used to get tokens to power | ||
| interactions with Globus APIs, and SDK's :class:`globus_sdk.GlobusApp` and | ||
| :class:`globus_sdk.ClientCredentialsAuthorizer` will automatically cache and | ||
| reload these tokens appropriately. | ||
|
|
||
| .. note:: | ||
|
|
||
| In order to be used as a Service Account, a client must have an ID and secret. | ||
| However, not every client with an ID and secret supports this usage! Clients | ||
| may be registered with various different OAuth2 grant types enabled, and some | ||
| clients have an ID and secret but are used to authenticate user logins! | ||
|
|
||
| Put another way: having client credentials is *necessary but not sufficient* | ||
| for this kind of usage. | ||
|
|
||
|
|
||
| Disambiguation: "Clients" vs "Client Identities" vs "Service Accounts" | ||
| ---------------------------------------------------------------------- | ||
|
|
||
| There are two different meanings for the word "client", from different domains. | ||
|
|
||
| Conventionally, a library's adapter for a web API is a "client". | ||
| In the SDK, we primarily use the word "client" to refer to these API connectors, | ||
| as in ``TransferClient``, ``GroupsClient``, etc. | ||
|
|
||
| OAuth2 calls an application registered with the service a "client". | ||
| A "Client Identity" is a Globus Auth concept which uses this meaning of | ||
| "client". | ||
|
|
||
| As a result of this ambiguity, this documentation will prefer to refer to | ||
| "Client Identities" as "Service Accounts", which is the term which is used in | ||
| other Globus documentation and the web interface. | ||
|
|
||
|
|
||
| Service Account Permissions | ||
| --------------------------- | ||
|
|
||
| Service Accounts have their own assigned identities, group memberships, and | ||
| permissions within Globus. | ||
| They are not implicitly linked in any way to the user who created them, or the | ||
| administrators who manage them. | ||
| Their permissions are isolated. | ||
|
|
||
| Users of Service Accounts need to separately assign permissions to these | ||
| identities, depending on what resources the client is meant to access. | ||
|
|
||
|
|
||
| Policies Which Conflict With Service Accounts | ||
| --------------------------------------------- | ||
|
|
||
| A number of the configurable policies on Globus resources conflict with use of | ||
| Service Accounts. | ||
| Users often find that they cannot substitute Service Accounts for their own | ||
| credentials without also adapting their workflows or configurations to support | ||
| this usage. | ||
|
|
||
| In particular, users should be aware of the following classes of issues, and | ||
| potential workarounds. | ||
|
|
||
| Identity-specific Permissions | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| Because clients are not associated with their owners, identity-specific | ||
| permissions for users can't be directly "shared" with their clients. | ||
|
|
||
| If your account has permissions to access a resource, but you wish to use a | ||
| Service Account to interact with it, add a second permission to give the Service | ||
| Account access as well. | ||
|
|
||
| Domain Requirements | ||
| ~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| Resources may apply policies which require a specific domain for users. | ||
| For example, a University of Chicago Collection may require ``uchicago.edu`` | ||
| usernames. | ||
|
|
||
| Service Accounts have a fixed domain of ``clients.auth.globus.org`` and | ||
| therefore cannot satisfy these requirements. | ||
|
|
||
| Use user-specific access policies or permissions delegation features, like Guest | ||
| Collections, to allow Service Accounts to specifically access resources. | ||
|
|
||
| Session Timeouts | ||
| ~~~~~~~~~~~~~~~~ | ||
|
|
||
| Globus resources may configure authentication timeouts, forcing users to | ||
| reauthenticate within a fixed time window to use a resource. | ||
| This is done by checking the Globus Auth session associated with the user's | ||
| tokens for last authentication times. | ||
|
|
||
| For example, a Collection may require that users have logged in within the last | ||
| hour to access data -- this is part of the suite of features for High Assurance | ||
| data access. | ||
|
|
||
| A Service Account authenticates each time it fetches a token, but does not have | ||
| a Globus Auth session associated with those authentications. (There is no | ||
| browser session interaction in such cases.) | ||
| As such, a Service Account cannot satisfy these policies under a naive | ||
| interpretation. | ||
|
|
||
| Globus Connect Server implements a special rule to handle this case: session | ||
| timeouts are never enforced on Service Accounts. | ||
| Other services may implement similar policies or require that access to Service | ||
| Accounts be configured separately from regular user permissions. | ||
27 changes: 27 additions & 0 deletions
27
docs/user_guide/usage_patterns/service_accounts/using_client_app/client_app_ls.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| import globus_sdk | ||
|
|
||
| # your client credentials | ||
| CLIENT_ID = "YOUR ID HERE" | ||
| CLIENT_SECRET = "YOUR SECRET HERE" | ||
|
|
||
| # the ID of "tutorial collection 1" | ||
| TUTORIAL_COLLECTION = "6c54cade-bde5-45c1-bdea-f4bd71dba2cc" | ||
|
|
||
| # create a ClientApp named "app" | ||
| with globus_sdk.ClientApp( | ||
| "sample-app", | ||
| client_id=CLIENT_ID, | ||
| client_secret=CLIENT_SECRET, | ||
| config=globus_sdk.GlobusAppConfig(token_storage="memory"), | ||
| ) as app: | ||
| # create a TransferClient named "tc", bound to "app" | ||
| with globus_sdk.TransferClient(app=app) as tc: | ||
|
|
||
| # because the tutorial collection is of a type which uses a `data_access` | ||
| # scope for fine grained access control, the `data_access` requirement needs | ||
| # to be registered with the app | ||
| tc.add_app_data_access_scope(TUTORIAL_COLLECTION) | ||
|
|
||
| # iterate over the listing results, printing each filename | ||
| for entry in tc.operation_ls(TUTORIAL_COLLECTION, path="/home/share/godata"): | ||
| print(entry["name"]) |
97 changes: 97 additions & 0 deletions
97
docs/user_guide/usage_patterns/service_accounts/using_client_app/index.rst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| .. _userguide_using_client_app: | ||
|
|
||
| Using a ClientApp with a Service Account | ||
| ======================================== | ||
|
|
||
| Once you have a client ID and secret from an app registration for a service | ||
| account, the SDK has a few tools which can use those credentials to acquire | ||
| tokens, to talk to various Globus Services. | ||
|
|
||
| The easiest tool for this job is a ``ClientApp``, a flavor of ``GlobusApp`` | ||
| designed to work with service accounts. | ||
|
|
||
| Instantiating a ClientApp | ||
| ------------------------- | ||
|
|
||
| Constructing an app takes three required parameters, | ||
|
|
||
| - a human readable name to identify your app in HTTP requests and token caching (e.g., "My Cool Weathervane"). | ||
| - this does not need match the name you supplied during client registration. | ||
| - the client ID | ||
| - the client secret | ||
|
|
||
| as in: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| import globus_sdk | ||
|
|
||
| CLIENT_ID = "YOUR ID HERE" | ||
| CLIENT_SECRET = "YOUR SECRET HERE" | ||
|
|
||
| app = globus_sdk.ClientApp( | ||
| "sample-app", | ||
| client_id=CLIENT_ID, | ||
| client_secret=CLIENT_SECRET, | ||
| ) | ||
|
|
||
| Using the App with a Globus Service | ||
| ----------------------------------- | ||
|
|
||
| The resulting app can then be passed to any SDK client class to create an API | ||
| client object which uses the app for authentication requirements. | ||
| For example, to use the ``app`` object to run an ``ls`` on one of the tutorial | ||
| collections: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| TUTORIAL_COLLECTION = "6c54cade-bde5-45c1-bdea-f4bd71dba2cc" | ||
|
|
||
| with globus_sdk.TransferClient(app=app) as tc: | ||
| tc.add_app_data_access_scope(TUTORIAL_COLLECTION) | ||
| ls_result = tc.operation_ls(TUTORIAL_COLLECTION, path="/home/share/godata") | ||
|
|
||
| .. note:: | ||
|
|
||
| Unfortunately, there are two different meanings of the word "client" in use | ||
| in this example! | ||
|
|
||
| A ``TransferClient`` is a "client" in the sense that it is a local object | ||
| which provides access to the Globus Transfer Service. | ||
| The ``CLIENT_ID``, ``CLIENT_SECRET``, and ``ClientApp`` are all using the | ||
| word "client" in reference to the OAuth2 standard's definition of a "client" | ||
| as a registered app, a different meaning for the same word. | ||
|
|
||
| Using Memory Storage | ||
| -------------------- | ||
|
|
||
| Unlike user logins, client credentials can't be "logged out" vs "logged in" -- | ||
| unless they are deleted via the Globus Auth service, they are always active. | ||
|
|
||
| As a result, unlike applications which provide user logins, ``ClientApp``\s will | ||
| very often prefer to store any tokens they are using in memory. The tokens will | ||
| be cached and reused over the lifetime of the process, but never persisted to | ||
| disk. | ||
|
|
||
| To configure an app in this way, simply add a ``config`` to the app | ||
| initialization to select the ``"memory"`` storage type: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| app = globus_sdk.ClientApp( | ||
| "sample-app", | ||
| client_id=CLIENT_ID, | ||
| client_secret=CLIENT_SECRET, | ||
| config=globus_sdk.GlobusAppConfig(token_storage="memory"), | ||
| ) | ||
|
|
||
| Complete Example | ||
| ---------------- | ||
|
|
||
| In addition to leveraging all of the elements described above, this example enhances the code sample to | ||
| use the ``ClientApp``'s context manager interface to close token storage. | ||
| We also add a loop of ``print()`` usages on the ``ls`` result to show some output: | ||
|
|
||
| .. literalinclude:: client_app_ls.py | ||
| :caption: ``client_app_ls.py`` [:download:`download <client_app_ls.py>`] | ||
| :language: python |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.