This guide explains how to use OAuth2-protected APIs as data sources in the MDS EDC Connector.
The MDS EDC Connector supports OAuth2 authentication for HTTP data sources (provider side). This allows secure integration with OAuth2-protected APIs without exposing credentials in the dataspace.
OAuth2 support enables Providers to share data from OAuth2-protected APIs.
⚠️ IMPORTANT - Consumer Side LimitationWhile the EDC framework technically supports OAuth2 for both data sources and data sinks, there was a security vulnerability (CVE-2024-4536) in the consumer-side implementation that was removed in eclipse-edc/Connector#4152. The EDC committer group recommends using OAuth2 primarily on the provider side. If consumer-side OAuth2 is required, conduct a thorough security assessment considering the potential security flaws.
The following properties configure OAuth2 authentication for data addresses:
| Property | Description | Required |
|---|---|---|
oauth2:tokenUrl |
OAuth2 token endpoint URL where access tokens are obtained | Yes |
oauth2:clientId |
OAuth2 client ID for authentication | Yes |
oauth2:clientSecretKey |
Vault key containing the client secret (not the secret itself) | Yes |
- Client Secret Storage: The
oauth2:clientSecretKeyproperty references a key in HashiCorp Vault, not the actual secret value - Manual Vault Setup: You must manually add the client secret to Vault before using it
- Token Management: The connector automatically obtains and refreshes access tokens as needed.
Use this when you want to provide data from an OAuth2-protected API through your EDC connector.
Before creating the asset, add the client secret to your Vault. The vault key you'll reference in the asset is: my-api-secret
If using the EDC UI to create an asset:
- Navigate to the asset creation page
- Select
Custom Datasource Config (JSON) - Provide the following JSON:
{
"https://w3id.org/edc/v0.0.1/ns/type": "HttpData",
"https://w3id.org/edc/v0.0.1/ns/baseUrl": "https://api.example.com/protected-endpoint",
"oauth2:tokenUrl": "https://auth.example.com/oauth/token",
"oauth2:clientId": "your-client-id",
"oauth2:clientSecretKey": "my-api-secret"
}Replace:
https://api.example.com/protected-endpoint- The OAuth2-protected API endpointhttps://auth.example.com/oauth/token- OAuth2 token endpointyour-client-id- Your OAuth2 client IDmy-api-secret- Vault key containing the client secret
To create an OAuth2-protected asset programmatically:
Endpoint: POST /api/management/v3/assets
Headers:
X-Api-Key: YourApiKey
Content-Type: application/json
Request Body:
{
"@context": {
"@vocab": "https://w3id.org/edc/v0.0.1/ns/",
"dcat": "http://www.w3.org/ns/dcat#",
"dct": "http://purl.org/dc/terms/",
"owl": "http://www.w3.org/2002/07/owl#",
"mobilitydcatap": "https://w3id.org/mobilitydcat-ap/",
"mobilitydcatap-theme": "https://w3id.org/mobilitydcat-ap/mobility-theme/",
"adms": "http://www.w3.org/ns/adms#",
"edc": "https://w3id.org/edc/v0.0.1/ns/",
"skos": "http://www.w3.org/2004/02/skos/core#",
"rdf": "http://www.w3.org/2000/01/rdf-schema#"
},
"@type": "Asset",
"@id": "oauth2-protected-asset-1",
"properties": {
"dct:title": "My OAuth2 Asset",
"mobilitydcatap:mobilityTheme": {
"mobilitydcatap-theme:data-content-category": "INFRASTRUCTURE_AND_LOGISTICS"
}
},
"dataAddress": {
"@type": "DataAddress",
"type": "HttpData",
"baseUrl": "https://api.example.com/protected-endpoint",
"oauth2:tokenUrl": "https://auth.example.com/oauth/token",
"oauth2:clientId": "your-client-id",
"oauth2:clientSecretKey": "my-api-secret"
}
}When a consumer initiates a transfer:
- Consumer negotiates contract and starts transfer
- Provider's data plane needs to fetch data from the OAuth2-protected source
- Data plane checks Vault for the client secret using
oauth2:clientSecretKey - Data plane requests access token from the
oauth2:tokenUrlusing client credentials - Data plane uses the access token to authenticate requests to
baseUrl - Data is fetched and transferred to the consumer
Before creating OAuth2-protected assets, you must add the client secret to your HashiCorp Vault instance.
content field.
Correct Vault Secret Structure:
{
"content": "your-actual-client-secret-value"
}Common Mistake - Do NOT store the secret like this:
{
"clientSecret": "your-secret-value"
}or just:
your-secret-value
The secret must be stored as a value inside the content field.
Using Vault CLI:
# Add the client secret
vault kv put secret/my-api-secret \
content='your-actual-client-secret-value'Using Vault UI:
- Navigate to
secret/path - Create new secret with key:
my-api-secret - Add a field named
content - Set the value to your client secret:
your-actual-client-secret-value
Using curl:
curl -X POST \
-H "X-Vault-Token: $VAULT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"content":"your-actual-client-secret-value"}' \
http://vault:8200/v1/secret/my-api-secretVerification:
Verify the secret is stored correctly:
# Retrieve the secret
vault kv get -format=json secret/my-api-secret
# Should return:
{
"data": {
"content": "your-actual-client-secret-value"
}
}If your OAuth2 client secret is super-secret-weather-key-12345, store it in Vault like this:
vault kv put secret/weather-api-secret \
content='super-secret-weather-key-12345'Then reference it in your asset configuration:
{
"oauth2:clientSecretKey": "weather-api-secret"
}{
"@context": {
"@vocab": "https://w3id.org/edc/v0.0.1/ns/",
"dcat": "http://www.w3.org/ns/dcat#",
"dct": "http://purl.org/dc/terms/",
"owl": "http://www.w3.org/2002/07/owl#",
"mobilitydcatap": "https://w3id.org/mobilitydcat-ap/",
"mobilitydcatap-theme": "https://w3id.org/mobilitydcat-ap/mobility-theme/",
"adms": "http://www.w3.org/ns/adms#",
"edc": "https://w3id.org/edc/v0.0.1/ns/",
"skos": "http://www.w3.org/2004/02/skos/core#",
"rdf": "http://www.w3.org/2000/01/rdf-schema#"
},
"@type": "Asset",
"@id": "weather-data-munich",
"properties": {
"dct:title": "Munich Weather Data",
"mobilitydcatap:mobilityTheme": {
"mobilitydcatap-theme:data-content-category": "INFRASTRUCTURE_AND_LOGISTICS"
}
},
"dataAddress": {
"@type": "DataAddress",
"type": "HttpData",
"baseUrl": "https://api.weather-service.com/v1/current?city=Munich",
"oauth2:tokenUrl": "https://auth.weather-service.com/oauth/token",
"oauth2:clientId": "mds-connector-client",
"oauth2:clientSecretKey": "weather-api-secret"
}
}