-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Document machine-to-machine auth options in openeo
- Loading branch information
Showing
3 changed files
with
237 additions
and
24 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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,226 @@ | ||
--- | ||
title: "Authentication in openEO" | ||
--- | ||
|
||
|
||
While basic the discovery of openEO collections and processes is possible without authentication, | ||
the actual execution of openEO workflows requires a user to be authenticated, | ||
to properly manage user quotas, resources, and credit consumption. | ||
User authentication in openEO is handled with the OpenID Connect protocol (often abbreviated as "OIDC"). | ||
|
||
The openEO endpoint of the Copernicus Data Space Ecosystem is configured to use | ||
Copernicus Data Space Ecosystem's own identity provider service. | ||
It is therefor recommended to complete your | ||
[Copernicus Data Space Ecosystem registration](../../Registration.qmd) | ||
before attempting to authenticate with openEO. | ||
|
||
|
||
## Getting Started: A Typical openEO Authentication Flow With The openEO Python Client Library {#sec-typical-authentication-flow} | ||
|
||
A typical Copernicus Data Space Ecosystem openEO workflow, | ||
using the openEO Python client library, | ||
starts with setting up a connection like this: | ||
|
||
```python | ||
import openeo | ||
|
||
connection = openeo.connect(url="openeo.dataspace.copernicus.eu") | ||
connection.authenticate_oidc() | ||
``` | ||
|
||
After connecting to the Copernicus Data Space Ecosystem openEO endpoint, | ||
[`Connection.authenticate_oidc()`](https://open-eo.github.io/openeo-python-client/api.html#openeo.rest.connection.Connection.authenticate_oidc){target="_blank"} initiates the OpenID Connect authentication flow: | ||
|
||
- By default, the first time `authenticate_oidc()` is called, | ||
instructions to visit a certain URL will be printed, e.g.: | ||
|
||
``` | ||
Visit https://auth.example/?user_code=EAXD-RQXV to authenticate. | ||
``` | ||
Visit this URL (click it or copy-paste it into your web browser) | ||
and follow the login flow using your Copernicus Data Space Ecosystem credentials. | ||
::: {.callout-tip collapse="false"} | ||
You can visit this URL with any browser you prefer to complete the login procedure | ||
(e.g. on your laptop or smartphone). | ||
It does *not* have to be a browser running on the same machine/network as your Python script/application. | ||
::: | ||
Once the authentication is completed, your Python script will receive | ||
the necessary authentication tokens and print | ||
``` | ||
Authorized successfully. | ||
``` | ||
- Other times, when you still have valid (refresh) tokens on your system, | ||
the openEO Python client library will automatically use these tokens and not make you go through a manual login process. | ||
You will immediately see | ||
``` | ||
Authenticated using refresh token. | ||
``` | ||
In any case, your `connection` is now authenticated and capable to make download/processing requests. | ||
## Alternative Authentication Methods | ||
The [openEO Python client library documentation](https://open-eo.github.io/openeo-python-client/auth.html){target="_blank"} | ||
has a more in-depth information of various authentication concepts, | ||
and discusses alternative authentication methods. | ||
## Non-interactive And Machine-to-Machine Authentication with the openEO Python client library | ||
@sec-typical-authentication-flow describes the typical authentication flow for interactive use cases, | ||
e.g. when working in a Jupyter notebook or manually running a script on your local machine. | ||
In this section we will discuss authentication approaches | ||
that are more fitting for *non-interactive* and *machine-to-machine* use cases. | ||
The practical aspects will be based on the openEO Python client library, | ||
but the concepts are generally applicable to other openEO client libraries as well. | ||
### Refresh Tokens | ||
Refresh tokens are long-lived tokens (order of weeks or months) | ||
that can be used to obtain new access tokens | ||
without the need for the user to re-authenticate. | ||
As mentioned in @sec-typical-authentication-flow, | ||
[`Connection.authenticate_oidc()`](https://open-eo.github.io/openeo-python-client/api.html#openeo.rest.connection.Connection.authenticate_oidc){target="_blank"} | ||
will require you to go through an interactive login flow in a browser, | ||
when there is no (valid) refresh token available. | ||
But when the openEO Python client library can find a valid refresh token on your system, | ||
this will be a non-interactive operation. | ||
This makes it a viable option for non-interactive and machine-to-machine authentication, | ||
if it is feasible to produce a new refresh token once in a while using an interactive login flow. | ||
To get this working, there are basically two aspects to cover | ||
(both of which have built-in support in the openEO Python client library): | ||
1. Obtain and store a new refresh token. | ||
There are several authentication methods on the `Connection` object | ||
(e.g. the often used `authenticate_oidc()` method) | ||
and most these have an option `store_refresh_token` | ||
to enable storing of the refresh token obtained during the authentication process. | ||
Note that this is enabled by default in `authenticate_oidc()`, | ||
but not in `authenticate_oidc_device()`. | ||
The refresh token is stored in private JSON file, | ||
by default in a folder under your user's personal data folder | ||
(typically determined by environment variables like | ||
`XDG_DATA_HOME` on Linux or `APPDATA` on Windows). | ||
The folder can also be configured directly with the | ||
`OPENEO_CONFIG_HOME` environment variable. | ||
The actual location can be verified | ||
with the [`openeo-auth` command line tool](https://open-eo.github.io/openeo-python-client/auth.html#auth-config-files-and-openeo-auth-helper-tool){target="_blank"}. | ||
2. Load and use the refresh token | ||
When you have a valid refresh token stored in a location | ||
for the openEO Python client library to find, | ||
you can authenticate directly with: | ||
```python | ||
connection.authenticate_oidc_refresh_token() | ||
``` | ||
Alternatively: | ||
- If you want to keep your logic generic, you can also use | ||
```python | ||
connection.authenticate_oidc() | ||
``` | ||
This method will first try to use a refresh token if available, | ||
and fall back on other methods (e.g. device code flow) otherwise. | ||
- If you manage store/load the refresh token yourself, | ||
you can explicitly pass it: | ||
```python | ||
connection.authenticate_oidc_refresh_token( | ||
refresh_token=your_refresh_token, | ||
) | ||
``` | ||
::: {.callout-tip} | ||
## Advanced refresh token storage | ||
For advanced use cases, it is also possible to override the file based | ||
refresh token storage with a custom implementation through the | ||
`refresh_token_store` parameter of | ||
[`Connection`](https://open-eo.github.io/openeo-python-client/api.html#openeo.rest.connection.Connection){target="_blank"}. | ||
::: | ||
### Client Credentials Flow | ||
OpenID Connect also supports the so-called "client credentials flow", | ||
which is a non-interactive flow, based on a client id and a secret, | ||
that is suitable for machine-to-machine authentication. | ||
The openEO Python client library has built-in support for this flow, | ||
with the ['authenticate_oidc_client_credentials()` method](https://open-eo.github.io/openeo-python-client/auth.html#oidc-authentication-client-credentials-flow){target="_blank"}: | ||
```python | ||
connection.authenticate_oidc_client_credentials( | ||
client_id=..., | ||
client_secret=..., # Note: Do not hard-code your secret here! | ||
) | ||
``` | ||
|
||
#### Obtaining Client Credentials | ||
|
||
::: {.callout-warning} | ||
Usage of client credentials in openEO is an experimental feature, | ||
it's not widely supported across openEO backends, | ||
and the setup procedure is not fully standardized or streamlined yet. | ||
::: | ||
|
||
The Sentinel Hub service in the Copernicus Data Space Ecosystem | ||
has a [dashboard web app](https://shapps.dataspace.copernicus.eu/dashboard) | ||
and under the account settings there is a self-service feature to | ||
[register your own OAuth client](../SentinelHub/Overview/Authentication.qmd#registering-oauth-client){target="_blank"}. | ||
The client id and client secret you obtain here can also be used | ||
for the client credentials flow with the openEO service of Copernicus Data Space Ecosystem. | ||
|
||
#### Caveats And Considerations | ||
|
||
- Treat your client secret securely, like a password. | ||
Take extra care to not leak it accidentally. | ||
For example, the simplicity of the `authenticate_oidc_client_credentials()` example snippet above, | ||
make it very tempting to just hard-code the client secret in your scripts or notebooks, | ||
which might then eventually be stored for eternity in some version control repository. | ||
|
||
Instead, read the client secret from a secure location | ||
(e.g. a private file outside the reach of your version control repositories), | ||
or leverage environment variables (e.g as directly [supported by the openEO Python client library](https://open-eo.github.io/openeo-python-client/auth.html#oidc-client-credentials-using-environment-variables){target="_blank"}). | ||
- The client credentials only identify your (OAuth) client, not your personal user account. | ||
|
||
- This means that openEO resources such as openEO batch jobs, their results, UDP's, etc | ||
from one identity are not available to the other. | ||
For example, you can not list the batch jobs created with client credentials, | ||
when you are using your personal account. | ||
- Likewise, the balances of processing credits are separate. | ||
It is however possible to link the balance of the client credentials account | ||
to your personal account. | ||
To enable that: contact support and provide your client id and user id. | ||
|
||
- The client credentials flow is not supported on the | ||
[Copernicus Data Space Ecosystem openEO web editor](https://openeo.dataspace.copernicus.eu/). | ||
As mentioned above, this practically means that you can not use it | ||
to track the progress and status of the batch jobs created with client credentials. | ||
However, it is still possible to approximate the batch job overview of the web editor | ||
with a Jupyter notebook using the openEO Python client library. | ||
|
This file contains 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