Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ssi): add credential issuer and credential subject id validation rules #548

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -119,15 +119,15 @@ spec:
# SSI / MIW CONFIGURATION
##########################
- name: "TX_SSI_MIW_URL"
value: {{ .Values.controlplane.ssi.miw.url }}
value: {{ .Values.controlplane.ssi.miw.url | quote }}
- name: "TX_SSI_MIW_AUTHORITY_ID"
value: {{ .Values.controlplane.ssi.miw.authorityId }}
value: {{ .Values.controlplane.ssi.miw.authorityId | quote }}
- name: "TX_SSI_OAUTH_TOKEN_URL"
value: {{ .Values.controlplane.ssi.oauth.tokenurl }}
value: {{ .Values.controlplane.ssi.oauth.tokenurl | quote }}
- name: "TX_SSI_OAUTH_CLIENT_ID"
value: {{ .Values.controlplane.ssi.oauth.client.id }}
value: {{ .Values.controlplane.ssi.oauth.client.id | quote }}
- name: "TX_SSI_OAUTH_CLIENT_SECRET_ALIAS"
value: {{ .Values.controlplane.ssi.oauth.client.secretAlias }}
value: {{ .Values.controlplane.ssi.oauth.client.secretAlias | quote }}
- name: "TX_SSI_ENDPOINT_AUDIENCE"
value: {{ printf "%s%s" (include "txdc.controlplane.url.protocol" .) .Values.controlplane.endpoints.protocol.path | quote }}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,15 +119,15 @@ spec:
# SSI / MIW CONFIGURATION
##########################
- name: "TX_SSI_MIW_URL"
value: {{ .Values.runtime.ssi.miw.url }}
value: {{ .Values.runtime.ssi.miw.url | quote }}
- name: "TX_SSI_MIW_AUTHORITY_ID"
value: {{ .Values.runtime.ssi.miw.authorityId }}
value: {{ .Values.runtime.ssi.miw.authorityId | quote }}
- name: "TX_SSI_OAUTH_TOKEN_URL"
value: {{ .Values.runtime.ssi.oauth.tokenurl }}
value: {{ .Values.runtime.ssi.oauth.tokenurl | quote }}
- name: "TX_SSI_OAUTH_CLIENT_ID"
value: {{ .Values.runtime.ssi.oauth.client.id }}
value: {{ .Values.runtime.ssi.oauth.client.id | quote }}
- name: "TX_SSI_OAUTH_CLIENT_SECRET_ALIAS"
value: {{ .Values.runtime.ssi.oauth.client.secretAlias }}
value: {{ .Values.runtime.ssi.oauth.client.secretAlias | quote }}
- name: "TX_SSI_ENDPOINT_AUDIENCE"
value: {{ printf "%s%s" (include "txdc.runtime.url.protocol" .) .Values.runtime.endpoints.protocol.path | quote }}

Expand Down
10 changes: 5 additions & 5 deletions charts/tractusx-connector/templates/deployment-controlplane.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -119,15 +119,15 @@ spec:
# SSI / MIW CONFIGURATION
##########################
- name: "TX_SSI_MIW_URL"
value: {{ .Values.controlplane.ssi.miw.url }}
value: {{ .Values.controlplane.ssi.miw.url | quote }}
- name: "TX_SSI_MIW_AUTHORITY_ID"
value: {{ .Values.controlplane.ssi.miw.authorityId }}
value: {{ .Values.controlplane.ssi.miw.authorityId | quote }}
- name: "TX_SSI_OAUTH_TOKEN_URL"
value: {{ .Values.controlplane.ssi.oauth.tokenurl }}
value: {{ .Values.controlplane.ssi.oauth.tokenurl | quote }}
- name: "TX_SSI_OAUTH_CLIENT_ID"
value: {{ .Values.controlplane.ssi.oauth.client.id }}
value: {{ .Values.controlplane.ssi.oauth.client.id | quote }}
- name: "TX_SSI_OAUTH_CLIENT_SECRET_ALIAS"
value: {{ .Values.controlplane.ssi.oauth.client.secretAlias }}
value: {{ .Values.controlplane.ssi.oauth.client.secretAlias | quote }}
- name: "TX_SSI_ENDPOINT_AUDIENCE"
value: {{ printf "%s%s" (include "txdc.controlplane.url.protocol" .) .Values.controlplane.endpoints.protocol.path | quote }}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.eclipse.edc.spi.agent.ParticipantAgent.PARTICIPANT_IDENTITY;
import static org.eclipse.tractusx.edc.iam.ssi.identity.extractor.fixtures.Credentials.SIMPLE_VP;
import static org.eclipse.tractusx.edc.iam.ssi.identity.extractor.fixtures.Credentials.SUMMARY_VP_NO_HOLDER;
import static org.eclipse.tractusx.edc.iam.ssi.identity.extractor.fixtures.Credentials.SUMMARY_VP_NO_SUBJECT;
import static org.eclipse.tractusx.edc.iam.ssi.spi.jsonld.CredentialsNamespaces.CX_SUMMARY_NS_V1;
import static org.eclipse.tractusx.edc.iam.ssi.spi.jsonld.CredentialsNamespaces.VP_PROPERTY;
import static org.eclipse.tractusx.edc.iam.ssi.spi.jsonld.JsonLdTextFixtures.createObjectMapper;
import static org.eclipse.tractusx.edc.iam.ssi.spi.jsonld.JsonLdTextFixtures.expand;
import static org.eclipse.tractusx.edc.iam.ssi.spi.jsonld.SummaryCredential.SIMPLE_VP;
import static org.eclipse.tractusx.edc.iam.ssi.spi.jsonld.SummaryCredential.SUMMARY_VP;
import static org.eclipse.tractusx.edc.iam.ssi.spi.jsonld.SummaryCredential.SUMMARY_VP_NO_HOLDER;
import static org.eclipse.tractusx.edc.iam.ssi.spi.jsonld.SummaryCredential.SUMMARY_VP_NO_SUBJECT;

public class CredentialIdentityExtractorTest {

Expand Down

This file was deleted.

19 changes: 11 additions & 8 deletions edc-extensions/ssi/ssi-miw-credential-client/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# MIW Client Credential Module

This module contains an implementation of the `SsiCredentialClient` interface for SSI.
It basically narrow down to two operations:
It basically narrows down to two operations:

- obtaining a token for protocol communication
- validating the token
Expand All @@ -13,10 +13,13 @@ For obtaining a `JWT` token also it reaches the MIW, that will create a token wi

## Configuration

| Key | Required | Example | Description |
|-----------------------------------------|----------|----------------|-----------------------------------|
| tx.ssi.miw.url | X | | MIW URL |
| tx.ssi.miw.authority.id | X | | BPN number of the authority |
| tx.ssi.oauth.token.url | X | | Token URL (Keycloak) |
| tx.ssi.oauth.client.id | X | | Client id |
| tx.ssi.oauth.client.secret.alias | X | | Vault alias for the client secret |
| Key | Required | Example | Description |
|----------------------------------|----------|----------------|-----------------------------------|
| tx.ssi.miw.url | X | | MIW URL |
| tx.ssi.miw.authority.id | X | | BPN number of the authority |
| tx.ssi.miw.authority.issuer | | | The id of the issuer (DID) |
| tx.ssi.oauth.token.url | X | | Token URL (Keycloak) |
| tx.ssi.oauth.client.id | X | | Client id |
| tx.ssi.oauth.client.secret.alias | X | | Vault alias for the client secret |

By default, the `tx.ssi.miw.authority.issuer` is composed with `did:web:<tx.ssi.miw.url>:<tx.ssi.miw.authority.id>
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@ dependencies {
implementation(libs.jakartaJson)
implementation(libs.nimbus.jwt)

testImplementation(testFixtures(project(":spi:ssi-spi")))
testImplementation(testFixtures(libs.edc.junit))
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@
import org.eclipse.edc.runtime.metamodel.annotation.Extension;
import org.eclipse.edc.runtime.metamodel.annotation.Inject;
import org.eclipse.edc.runtime.metamodel.annotation.Provider;
import org.eclipse.edc.runtime.metamodel.annotation.Setting;
import org.eclipse.edc.spi.http.EdcHttpClient;
import org.eclipse.edc.spi.monitor.Monitor;
import org.eclipse.edc.spi.system.ServiceExtension;
import org.eclipse.edc.spi.system.ServiceExtensionContext;
import org.eclipse.edc.spi.types.TypeManager;
import org.eclipse.tractusx.edc.iam.ssi.miw.api.MiwApiClient;
import org.eclipse.tractusx.edc.iam.ssi.miw.api.MiwApiClientImpl;
import org.eclipse.tractusx.edc.iam.ssi.miw.config.SsiMiwConfiguration;
import org.eclipse.tractusx.edc.iam.ssi.miw.oauth2.MiwOauth2Client;


Expand All @@ -33,12 +33,6 @@ public class SsiMiwApiClientExtension implements ServiceExtension {

public static final String EXTENSION_NAME = "SSI MIW Api Client";

@Setting(value = "MIW API base url")
public static final String MIW_BASE_URL = "tx.ssi.miw.url";

@Setting(value = "MIW Authority ID")
public static final String MIW_AUTHORITY_ID = "tx.ssi.miw.authority.id";

@Inject
private MiwOauth2Client oauth2Client;

Expand All @@ -51,18 +45,17 @@ public class SsiMiwApiClientExtension implements ServiceExtension {
@Inject
private Monitor monitor;

@Inject
private SsiMiwConfiguration miwConfiguration;

@Override
public String name() {
return EXTENSION_NAME;
}

@Provider
public MiwApiClient apiClient(ServiceExtensionContext context) {
var baseUrl = context.getConfig().getString(MIW_BASE_URL);
var authorityId = context.getConfig().getString(MIW_AUTHORITY_ID);


return new MiwApiClientImpl(httpClient, baseUrl, oauth2Client, context.getParticipantId(), authorityId, typeManager.getMapper(), monitor);
return new MiwApiClientImpl(httpClient, miwConfiguration.getUrl(), oauth2Client, context.getParticipantId(), miwConfiguration.getAuthorityId(), typeManager.getMapper(), monitor);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation
*
*/

package org.eclipse.tractusx.edc.iam.ssi.miw;

import org.eclipse.edc.runtime.metamodel.annotation.Extension;
import org.eclipse.edc.runtime.metamodel.annotation.Provider;
import org.eclipse.edc.runtime.metamodel.annotation.Setting;
import org.eclipse.edc.spi.system.ServiceExtension;
import org.eclipse.edc.spi.system.ServiceExtensionContext;
import org.eclipse.tractusx.edc.iam.ssi.miw.config.SsiMiwConfiguration;

import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

import static java.lang.String.format;


@Extension(SsiMiwConfigurationExtension.EXTENSION_NAME)
public class SsiMiwConfigurationExtension implements ServiceExtension {


@Setting(value = "MIW API base url")
public static final String MIW_BASE_URL = "tx.ssi.miw.url";
@Setting(value = "MIW Authority ID")
public static final String MIW_AUTHORITY_ID = "tx.ssi.miw.authority.id";
@Setting(value = "MIW Authority Issuer")
public static final String MIW_AUTHORITY_ISSUER = "tx.ssi.miw.authority.issuer";
public static final String AUTHORITY_ID_TEMPLATE = "did:web:%s:%s";
protected static final String EXTENSION_NAME = "SSI Miw configuration extension";

@Provider
public SsiMiwConfiguration miwConfiguration(ServiceExtensionContext context) {
var baseUrl = context.getConfig().getString(MIW_BASE_URL);
var authorityId = context.getConfig().getString(MIW_AUTHORITY_ID);
var authorityIssuer = authorityIssuer(context, baseUrl, authorityId);

return SsiMiwConfiguration.Builder.newInstance()
.url(baseUrl)
.authorityId(authorityId)
.authorityIssuer(authorityIssuer)
.build();
}


private String authorityIssuer(ServiceExtensionContext context, String baseUrl, String authorityId) {
var uri = URI.create(baseUrl);
var defaultAuthorityIssuer = format(AUTHORITY_ID_TEMPLATE, URLEncoder.encode(uri.getAuthority(), StandardCharsets.UTF_8), authorityId);
return context.getConfig().getString(MIW_AUTHORITY_ISSUER, defaultAuthorityIssuer);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0
*
* SPDX-License-Identifier: Apache-2.0
*
* Contributors:
* Bayerische Motoren Werke Aktiengesellschaft (BMW AG) - initial API and implementation
*
*/

package org.eclipse.tractusx.edc.iam.ssi.miw;

import org.eclipse.edc.runtime.metamodel.annotation.Extension;
import org.eclipse.edc.runtime.metamodel.annotation.Inject;
import org.eclipse.edc.spi.monitor.Monitor;
import org.eclipse.edc.spi.system.ServiceExtension;
import org.eclipse.edc.spi.system.ServiceExtensionContext;
import org.eclipse.tractusx.edc.iam.ssi.miw.config.SsiMiwConfiguration;
import org.eclipse.tractusx.edc.iam.ssi.miw.rule.SsiCredentialIssuerValidationRule;
import org.eclipse.tractusx.edc.iam.ssi.miw.rule.SsiCredentialSubjectIdValidationRule;
import org.eclipse.tractusx.edc.iam.ssi.spi.SsiValidationRuleRegistry;

@Extension(SsiMiwValidationRuleExtension.EXTENSION_NAME)
public class SsiMiwValidationRuleExtension implements ServiceExtension {

protected static final String EXTENSION_NAME = "SSI MIW validation rules extension";
@Inject
private SsiValidationRuleRegistry registry;

@Inject
private Monitor monitor;

@Inject
private SsiMiwConfiguration miwConfiguration;

@Override
public String name() {
return EXTENSION_NAME;
}

@Override
public void initialize(ServiceExtensionContext context) {
registry.addRule(new SsiCredentialSubjectIdValidationRule(monitor));
registry.addRule(new SsiCredentialIssuerValidationRule(miwConfiguration.getAuthorityIssuer(), monitor));
}
}
Loading