Verifying API tokens

Introduction §

Data sources that are set to use the Dataspace verified API tokens access control mode will in each request coming from the product gateway on the dataspace receive an API token in the X-API-Key HTTP Header.

There are two main ways a data source can verify this API token:

  1. Validate the token as a JWT signed by the dataspace
  2. Use the token verification endpoint on the product gateway

Validate token as a JWT signed by the dataspace §

The API token is actually a JWT token signed by the dataspace and can easily be verified using most common JWT libraries.

As an example here’s a token that has been verified and decoded using the https://jwt.io service:

Interface of JWT.io showing tje decoded and verified token.

To verify the token you need to find the public keys of the dataspace. They can be found by checking the /.well-known/dataspace/dataspace-configuration.json on the base domain of the dataspace and locating the jwks_url. For example the dataspace configuration on ioxio.io points to https://ioxio.io/.well-known/jwks.json .

Things to ensure:

  • The aud must match the DSI (Data Source Identifier) of your source. This is critical to verify! If you don’t verify this and someone else figures out the address at which your data source lives, they could publish it as their own data source on the same dataspace and grant access to it to anyone they want and get JWTs that are in all other aspects valid.
  • The token is signed with one of the keys of the dataspace.
  • The token hasn’t expired - make sure the exp is in the future and the iat is in the past (potentially allowing some reasonable leeway to account for clock differences, e.g. 5 minutes).
  • The issuer (iss) is the base URL of the dataspace, for example https://ioxio.io, on which you’ve published the data source.

In case you want to do some more fine-grained access control to what data who has access to, you can use the sub to identify the group access was granted to.

An example implementation can be found on https://github.com/ioxio-dataspace/example-productizer/blob/3dd2435183ed5cbbd30c99a473a8d9c2ccf6b7c7/app/api_tokens.py#L221-L278 .

Validating the token as a JWT in Azure API Management §

In Azure API Management you can use the Validate JWT inbound processing policy to validate the API Token from the X-API-Key header.

You should point the Open ID URLs to a URL of the form https://<dataspace-domain>/.well-known/openid-configuration. So for example for IOXIO.io you would set it to https://ioxio.io/.well-known/openid-configuration.

The Audiences should be set to match the DSI (Data Source Identifier) of your source. This is critical! If you don’t set this and someone else figures out the address of your API Management endpoint they could publish it as their own data source on the same dataspace and grant access to it to anyone they want and get JWTs that are in all other aspects valid.

The default values are to require an expiration time and to require the tokens to be signed, but we still encourage to explicitly set them.

You might also want to allow some clock skew, for example 5 minutes or 300 seconds should be more than enough.

You might also like output the parsed token to a variable for further processing. The sub field of the token identifies the group the access was granted to, so you might want to use it to check what data you want to give which group access to.

In the UI the configuration could look like this:

Azure API Management screen with inbound processing policy for validating JWT.

And in the code editor the configuration should look somewhat similar to this:

You might also find the documentation on validating JWTs in Azure API Management useful.

Token verification API §

The product gateway offers an endpoint at the path /api/v1/api-token/verify, for example on https://gateway.ioxio.io/api/v1/api-token/verify. It expects a POST request with a body of the form:

The aud needs to match the DSI (Data Source Identifier) of the source you are providing, the apiToken is the token from the request that you want to verify is valid for your data source.

In case of a valid token you will get a 200 OK response with "valid": true and some additional details of the token, similar to this:

In case the API token is not valid, you will get a 403 error response with "success": false, similar to this:

Any other possible errors should also be treated as failures.

Testing §

The Building a data source guide explains in the Test your data source using Swagger UI section how you can easily obtain an API token and use the Swagger UI to test your data source through the product gateway of the dataspace.

Swagger UI Responses section highlighting the curl command.

If you want to test the token validation works correctly also in your own implementation, you can simply copy the curl example that is shown there and replace the URL with the one for your own implementation (assuming you have curl installed and can run it in a terminal).

You can equally well make the request against your actual deployed instance or against your own local development setup by changing the URL to something like https://my-server.example.com/Meteorology/Weather_v0.1?source=my_group or http://localhost:8080/Meteorology/Weather_v0.1?source=my_group.

To test with invalid tokens you can let the token expire or you can make it invalid by removing the last character (the token consists of three parts, separated by dots ., the first one contains the header, the middle one the payload and the last part is the signature, so any change after the last dot will invalidate the signature, but keep the header and payload intact).

You could also register a temporary dummy data source using another variant when creating it or create it using a different definition just to be able to generate API tokens for them. API tokens generated for those sources should not be valid due to the differences in the aud field compared to the real source.

Granting access §

The Managing access to the data source section of the Building a data source guide also explains how to grant access to the data source to other groups and how to remove access. Granting them access means they will be able to generate API tokens with their group as the sub.

On this page