How to access restricted data with a token

Some data at eodc is only available to signed-in users or to users with approved access. This guide shows how to get a token for your eodc account and how to use it to find and download such data, both in the eodc data catalogue and in customer STAC catalogues.

Two catalogues, one token

eodc data catalogue (catalogue.services.eodc.eu)

Customer STAC catalogues (cstac.discovery.eodc.eu)

Finding collections and items

Open to everyone, no token

Token needed, unless the collection is public. Without a token, restricted collections don’t appear in /collections or /search.

Downloading data

Token needed for restricted collections and for collections that need an eodc account

If the data is hosted at eodc (data.eodc.eu): token needed, same as in the eodc data catalogue. If the data is hosted elsewhere: depends on that host.

The same token works for both catalogues and for downloads from data.eodc.eu. Send it in the Authorization header of every request:

Authorization: Bearer <token>

Access to a restricted collection comes from a group in your eodc account, for example /services/data-access/<group>. You get it after your access request is approved, see Get Access.

Get a token

The recommended way is EODCConnection from eodc-connect:

pip install eodc-connect
from getpass import getpass

from eodc_connect.auth import EODCConnection

conn = EODCConnection("your.name@example.org", getpass("Enter your password: "))
token = conn.get_access_token()

Tokens are short-lived. The lifetime in seconds is in conn.token["expires_in"]. In longer scripts, refresh the token before you use it:

if conn.is_token_expired():
    conn.refresh()
token = conn.get_access_token()

For clients other than Python, such as curl or GDAL on the command line, request the token directly from eodc’s identity service:

curl -s https://bouncer.eodc.eu/auth/realms/EODC/protocol/openid-connect/token \
  -d grant_type=password \
  -d client_id=eodc-connect \
  -d username=your.name@example.org \
  --data-urlencode password="$EODC_PASSWORD"

The response contains the token in access_token and its lifetime in seconds in expires_in.

Check your access

The groups of your account are in the token. To check them:

print(conn.access_token_decoded["groups"])

After you have been added to a group, for example after an approved access request, get a new token. Existing tokens don’t contain the new group.

eodc data catalogue: search without a token, download with a token

Searching works without a token. Downloading an asset needs it:

import requests
from pystac_client import Client

catalogue = Client.open("https://catalogue.services.eodc.eu")
item = next(catalogue.search(collections=["S1_SAR_COG"], bbox=[15, 47, 17, 49], max_items=1).items())
href = item.assets["VV"].href

response = requests.get(
    href,
    headers={"Authorization": f"Bearer {token}"},
    allow_redirects=False,
    timeout=60,
)
print(response.status_code)  # 302: ready to download, 202: being staged, try again later

A 302 points to a short-lived download link in response.headers["Location"]. Fetch that link without the Authorization header. For Copernicus Sentinel data, which can take a few minutes to be staged, see Copernicus Sentinel Data Access for a complete download loop.

Customer STAC catalogues: send the token with the search too

In a customer STAC catalogue, the token is also needed to find restricted collections. Pass it to pystac-client as a header:

from pystac_client import Client

cstac = Client.open(
    "https://cstac.discovery.eodc.eu",
    headers={"Authorization": f"Bearer {token}"},
)
print([collection.id for collection in cstac.get_collections()])

items = cstac.search(collections=["<collection-id>"], max_items=10).item_collection()

Always filter by collection when you search. Item IDs, such as tile names, can be the same in several collections.

Where the assets are downloaded from depends on where the data is hosted. The organisation that manages the collection decides this:

  • Hosted at eodc (asset links start with https://data.eodc.eu): download with the same token, as in the eodc data catalogue:

    href = items[0].assets["<asset-key>"].href
    response = requests.get(href, headers={"Authorization": f"Bearer {token}"}, timeout=60)
    
  • Hosted elsewhere (for example on a university’s own server): the asset links point to that server, and access depends on it. Your eodc token isn’t needed there. Don’t send it to hosts outside eodc.

Reading data directly with GDAL, rioxarray or odc-stac

GDAL-based tools read from URLs with HTTP range requests. For assets that data.eodc.eu serves directly, pass the token to GDAL as a header. GDAL then sends it with every request, so only set it when you read from data.eodc.eu:

import os

os.environ["GDAL_HTTP_HEADERS"] = f"Authorization: Bearer {token}"

For assets that data.eodc.eu answers with a 302 redirect (such as Copernicus Sentinel data), first request the download link as shown above, then open that link without the token. The link is signed for GET requests only, so turn off GDAL’s HEAD request:

import os
import rioxarray

os.environ["CPL_VSIL_CURL_USE_HEAD"] = "NO"
os.environ["GDAL_DISABLE_READDIR_ON_OPEN"] = "EMPTY_DIR"

da = rioxarray.open_rasterio(response.headers["Location"], masked=True)

Troubleshooting

What you see

Meaning

What to do

401 or 403 from data.eodc.eu

No token, the token has expired, or your account has no access to this collection

Get a new token or refresh it. If that doesn’t help, check your groups and request access.

401 from cstac.discovery.eodc.eu

The token is invalid or has expired

Get a new token or refresh it

Collection missing in cstac.discovery.eodc.eu (/collections/<id> returns 404, searches return no items)

No token sent, or your account has no access to this collection

Send the token. If it’s still missing, request access, then get a new token.

If you still can’t access data you have been approved for, contact support@eodc.eu with the collection ID and the time of the request.