Skip to content

Commit

Permalink
Document machine-to-machine auth options in openeo
Browse files Browse the repository at this point in the history
  • Loading branch information
soxofaan committed Sep 12, 2024
1 parent bcf8032 commit 5db908b
Show file tree
Hide file tree
Showing 3 changed files with 237 additions and 24 deletions.
33 changes: 9 additions & 24 deletions APIs/openEO/Python_Client/Python.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -136,34 +136,18 @@ just like this:
connection.authenticate_oidc()
```

- By default, the first time you call this `authenticate_oidc()` method,
a URL will be printed. Something like for example:
- By default, the first time `authenticate_oidc()` is called,
instructions to visit a certain URL will be printed, e.g.:

```
Visit https://auth.example.com/device?user_code=EAXD-RQXV to authenticate.
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="true"}
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.
```
Visit this URL and follow the login flow
using your Copernicus Data Space Ecosystem credentials.
- Other times, when you still have valid (refresh) tokens on your system,
it will not be necessary to go through the Copernicus Data Space Ecosystem login steps
and you will immediately see
the manual login process is skipped and you will immediately see
```
Authenticated using refresh token.
Expand All @@ -172,8 +156,9 @@ connection.authenticate_oidc()
In any case, your `connection` is now authenticated and capable to make download/processing requests.
A more in-depth discussion of various authentication concepts is available
in the [openEO Python client documentation](https://open-eo.github.io/openeo-python-client/auth.html){target="_blank"}.
Find more in-depth information on authentication
[here](../authentication.qmd)
or in the [openEO Python client documentation](https://open-eo.github.io/openeo-python-client/auth.html){target="_blank"}.
## Working with Datacube
Expand Down
226 changes: 226 additions & 0 deletions APIs/openEO/authentication.qmd
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.

2 changes: 2 additions & 0 deletions _quarto.yml
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ website:
text: openEO Processes
- href: "APIs/openEO/File_formats.qmd"
text: File Formats
- href: "APIs/openEO/authentication.qmd"
text: Authentication
- href: "https://open-eo.github.io/openeo-python-client"
text: Python documentation
target: "_blank"
Expand Down

0 comments on commit 5db908b

Please sign in to comment.