From d320f623d0a43351addd85cf9e4b8c236ce88f21 Mon Sep 17 00:00:00 2001 From: Simon Malok Date: Wed, 29 Jul 2026 10:05:14 +0200 Subject: [PATCH 1/9] feat: single edc setup --- bruno/single-node/bruno.json | 9 + .../environments/local-con-x-env.bru | 40 +++ .../ShowConsumerCredentials.bru | 33 +++ .../ShowProviderCredentials.bru | 27 ++ .../identities/Inspect Outcome/folder.bru | 12 + .../CreateConsumerParticipant.bru | 67 +++++ .../Get Consumer DID Doc.bru | 16 ++ .../RequestConsumerDevMemCredential.bru | 35 +++ .../Prepare Consumer ID/VaultSecret test.bru | 21 ++ .../Prepare Consumer ID/VaultSecret.bru | 29 ++ .../identities/Prepare Consumer ID/folder.bru | 13 + .../CreateIssuerParticipant.bru | 63 +++++ .../Prepare Issuer/Get Issuer DID Doc.bru | 16 ++ .../Prepare Issuer/addConsumerHolder.bru | 33 +++ .../Prepare Issuer/addProviderHolder.bru | 33 +++ .../Prepare Issuer/createDevAttestation.bru | 55 ++++ .../createDevMemCredentialDef.bru | 42 +++ .../identities/Prepare Issuer/folder.bru | 22 ++ .../CreateProviderParticipant.bru | 67 +++++ .../Get Provider DID Doc.bru | 16 ++ .../RequestProviderDevMemCredential.bru | 36 +++ .../Prepare Provider ID/VaultSecret test.bru | 21 ++ .../Prepare Provider ID/VaultSecret.bru | 29 ++ .../identities/Prepare Provider ID/folder.bru | 13 + .../Simulated DCP Flow/Consumer Token.bru | 35 +++ .../Simulated DCP Flow/Get Credential.bru | 47 ++++ .../Simulated DCP Flow/Provider Token.bru | 30 +++ .../identities/Simulated DCP Flow/folder.bru | 34 +++ bruno/single-node/identities/folder.bru | 8 + bruno/single-node/other/RevokeCred.bru | 20 ++ bruno/single-node/other/Version.bru | 20 ++ bruno/single-node/other/folder.bru | 8 + .../consumer/CheckNegotiationResult.bru | 31 +++ .../transactions/consumer/Get EDR.bru | 31 +++ .../consumer/InitPullTransfer.bru | 41 +++ .../consumer/InitiateNegotiation.bru | 53 ++++ .../transactions/consumer/PullAssetData.bru | 20 ++ .../consumer/RequestProviderCatalog.bru | 47 ++++ .../transactions/consumer/folder.bru | 24 ++ bruno/single-node/transactions/folder.bru | 11 + .../transactions/provider/CreateAsset.bru | 39 +++ .../provider/CreateContractDefinition.bru | 28 ++ .../transactions/provider/CreatePolicy.bru | 33 +++ .../transactions/provider/folder.bru | 16 ++ docker/single-node/.env.example | 7 + docker/single-node/README.md | 138 +++++++++- .../additional_config/logging.properties | 18 ++ .../additional_config/pg_init/pg_init.sql | 4 + .../connector/additional_config/vault-init.sh | 74 +++++ .../connector/docker-compose-memory.yaml | 240 +++++++++++++++++ .../single-node/connector/docker-compose.yaml | 254 ++++++++++++++++++ .../connector/vault/config/vault.hcl | 11 + .../single-node/traefik/traefik-compose.yaml | 29 ++ .../traefik/traefik-dynamic-conf.yaml | 210 +++++++++++++++ .../traefik/traefik-static-conf.yaml | 35 +++ 55 files changed, 2343 insertions(+), 1 deletion(-) create mode 100644 bruno/single-node/bruno.json create mode 100644 bruno/single-node/environments/local-con-x-env.bru create mode 100644 bruno/single-node/identities/Inspect Outcome/ShowConsumerCredentials.bru create mode 100644 bruno/single-node/identities/Inspect Outcome/ShowProviderCredentials.bru create mode 100644 bruno/single-node/identities/Inspect Outcome/folder.bru create mode 100644 bruno/single-node/identities/Prepare Consumer ID/CreateConsumerParticipant.bru create mode 100644 bruno/single-node/identities/Prepare Consumer ID/Get Consumer DID Doc.bru create mode 100644 bruno/single-node/identities/Prepare Consumer ID/RequestConsumerDevMemCredential.bru create mode 100644 bruno/single-node/identities/Prepare Consumer ID/VaultSecret test.bru create mode 100644 bruno/single-node/identities/Prepare Consumer ID/VaultSecret.bru create mode 100644 bruno/single-node/identities/Prepare Consumer ID/folder.bru create mode 100644 bruno/single-node/identities/Prepare Issuer/CreateIssuerParticipant.bru create mode 100644 bruno/single-node/identities/Prepare Issuer/Get Issuer DID Doc.bru create mode 100644 bruno/single-node/identities/Prepare Issuer/addConsumerHolder.bru create mode 100644 bruno/single-node/identities/Prepare Issuer/addProviderHolder.bru create mode 100644 bruno/single-node/identities/Prepare Issuer/createDevAttestation.bru create mode 100644 bruno/single-node/identities/Prepare Issuer/createDevMemCredentialDef.bru create mode 100644 bruno/single-node/identities/Prepare Issuer/folder.bru create mode 100644 bruno/single-node/identities/Prepare Provider ID/CreateProviderParticipant.bru create mode 100644 bruno/single-node/identities/Prepare Provider ID/Get Provider DID Doc.bru create mode 100644 bruno/single-node/identities/Prepare Provider ID/RequestProviderDevMemCredential.bru create mode 100644 bruno/single-node/identities/Prepare Provider ID/VaultSecret test.bru create mode 100644 bruno/single-node/identities/Prepare Provider ID/VaultSecret.bru create mode 100644 bruno/single-node/identities/Prepare Provider ID/folder.bru create mode 100644 bruno/single-node/identities/Simulated DCP Flow/Consumer Token.bru create mode 100644 bruno/single-node/identities/Simulated DCP Flow/Get Credential.bru create mode 100644 bruno/single-node/identities/Simulated DCP Flow/Provider Token.bru create mode 100644 bruno/single-node/identities/Simulated DCP Flow/folder.bru create mode 100644 bruno/single-node/identities/folder.bru create mode 100644 bruno/single-node/other/RevokeCred.bru create mode 100644 bruno/single-node/other/Version.bru create mode 100644 bruno/single-node/other/folder.bru create mode 100644 bruno/single-node/transactions/consumer/CheckNegotiationResult.bru create mode 100644 bruno/single-node/transactions/consumer/Get EDR.bru create mode 100644 bruno/single-node/transactions/consumer/InitPullTransfer.bru create mode 100644 bruno/single-node/transactions/consumer/InitiateNegotiation.bru create mode 100644 bruno/single-node/transactions/consumer/PullAssetData.bru create mode 100644 bruno/single-node/transactions/consumer/RequestProviderCatalog.bru create mode 100644 bruno/single-node/transactions/consumer/folder.bru create mode 100644 bruno/single-node/transactions/folder.bru create mode 100644 bruno/single-node/transactions/provider/CreateAsset.bru create mode 100644 bruno/single-node/transactions/provider/CreateContractDefinition.bru create mode 100644 bruno/single-node/transactions/provider/CreatePolicy.bru create mode 100644 bruno/single-node/transactions/provider/folder.bru create mode 100644 docker/single-node/.env.example create mode 100644 docker/single-node/connector/additional_config/logging.properties create mode 100644 docker/single-node/connector/additional_config/pg_init/pg_init.sql create mode 100644 docker/single-node/connector/additional_config/vault-init.sh create mode 100644 docker/single-node/connector/docker-compose-memory.yaml create mode 100644 docker/single-node/connector/docker-compose.yaml create mode 100644 docker/single-node/connector/vault/config/vault.hcl create mode 100644 docker/single-node/traefik/traefik-compose.yaml create mode 100644 docker/single-node/traefik/traefik-dynamic-conf.yaml create mode 100644 docker/single-node/traefik/traefik-static-conf.yaml diff --git a/bruno/single-node/bruno.json b/bruno/single-node/bruno.json new file mode 100644 index 0000000..6a1eba3 --- /dev/null +++ b/bruno/single-node/bruno.json @@ -0,0 +1,9 @@ +{ + "version": "1", + "name": "con-x-local-test", + "type": "collection", + "ignore": [ + "node_modules", + ".git" + ] +} \ No newline at end of file diff --git a/bruno/single-node/environments/local-con-x-env.bru b/bruno/single-node/environments/local-con-x-env.bru new file mode 100644 index 0000000..1d30224 --- /dev/null +++ b/bruno/single-node/environments/local-con-x-env.bru @@ -0,0 +1,40 @@ +vars { + ISSUER_DID_API: {{ISSUER_DOMAIN}} + ISSUER_ID_API: {{ISSUER_DOMAIN}}/api/identity + ISSUER_ISS_API: {{ISSUER_DOMAIN}}/api/issuer + CONSUMER_IDHUB_DID_API: {{CONSUMER_DOMAIN}} + CONSUMER_IDHUB_ID_API: {{CONSUMER_DOMAIN}}/api/identity + CONSUMER_IDHUB_STS_API: {{CONSUMER_DOMAIN}}/api/sts + CONSUMER_IDHUB_CREDS_API: {{CONSUMER_DOMAIN}}/api/credentials + ISSUER_APIKEY: ZGlkOndlYjpsb2NhbC1pc3N1ZXItc2VydmljZTpmeC1pc3N1ZXI=.CmYgVcuzneJXqzcbj7vmld5feejy6OguIylflSrz6WTjG1HNQRvO62EafFrQjS/lVlZAwiwz2rwwZgXrbpyhcg== + CONSUMER_IH_APIKEY: ZGlkOndlYjpsb2NhbC11c2VyLWlkaHViOnVzZXI6Y29uc3VtZXI=.ObFly02OtymUNRE43uH9SblWVtsZH0NMddgm1dFYQXRekO3qXX+rHFV7NvM+DUW3lcA2PbILt5rwWYEqm7WNgw== + PROVIDER_IH_APIKEY: ZGlkOndlYjpsb2NhbC11c2VyLWlkaHViOnVzZXI6cHJvdmlkZXI=.Knip+hedL63qedBQfOvZhhrF2ooSCfP2YgjONvtmehofor2ejdw/en0MAXDBZEcXrCwYNppDMNFDsRlG5rB/Mw== + CONSUMER_VAULTURL: {{CONSUMER_DOMAIN}} + CONSUMER_STS_SECRET: VD0q6jOEyslSeFV2 + PROVIDER_STS_SECRET: XjDk9ncaJSrSfkQW + PROVIDER_MANAGEMENT: {{PROVIDER_DOMAIN}}/management + CONSUMER_MANAGEMENT: {{CONSUMER_DOMAIN}}/management + PROVIDER_DATAPLANE_PUBLIC: {{PROVIDER_DOMAIN}}/public + PROVIDER_IDHUB_DID_API: {{PROVIDER_DOMAIN}} + PROVIDER_IDHUB_ID_API: {{PROVIDER_DOMAIN}}/api/identity + PROVIDER_IDHUB_STS_API: {{PROVIDER_DOMAIN}}/api/sts + PROVIDER_IDHUB_CREDS_API: {{PROVIDER_DOMAIN}}/api/credentials + ISS_ID: did:web:example.com + CONS_ID: did:web:example.com + PROV_ID: did:web:example.com + cons_access_token: eyJraWQiOiJkaWQ6d2ViOmNvbnN1bWVyLWlkaHViOnVzZXI6Y29uc3VtZXIja2V5LTEiLCJhbGciOiJFZDI1NTE5In0.eyJhdWQiOiJkaWQ6d2ViOmNvbnN1bWVyLWlkaHViOnVzZXI6Y29uc3VtZXIiLCJzdWIiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkaHViOnVzZXI6cHJvdmlkZXIiLCJuYmYiOjE3NzAyNzg5NTQsInNjb3BlIjoib3JnLmVjbGlwc2UudHJhY3R1c3gudmMudHlwZTpNZW1iZXJzaGlwQ3JlZGVudGlhbDpyZWFkIiwiaXNzIjoiZGlkOndlYjpjb25zdW1lci1pZGh1Yjp1c2VyOmNvbnN1bWVyIiwiZXhwIjoxNzcwMjc5MjU0LCJpYXQiOjE3NzAyNzg5NTQsImp0aSI6ImFjY2Vzc3Rva2VuLTcxYThmNTA5LTgwYTktNDMwZC1iMjU0LTMxNGFiYTBkNjY5OSJ9.ipRpdi_Ekh7y4IIqhqLgHU35Fn7NNkv6e6hILXy8pZObdy33y3MKppI61424eyHwqzmh7X2kwV2S5gDy3aOKCQ + prov_access_token: eyJraWQiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkaHViOnVzZXI6cHJvdmlkZXIja2V5LTEiLCJhbGciOiJFZDI1NTE5In0.eyJzdWIiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkaHViOnVzZXI6cHJvdmlkZXIiLCJhdWQiOiJkaWQ6d2ViOmNvbnN1bWVyLWlkaHViOnVzZXI6Y29uc3VtZXIiLCJuYmYiOjE3NzAyNzg5NTUsImlzcyI6ImRpZDp3ZWI6cHJvdmlkZXItaWRodWI6dXNlcjpwcm92aWRlciIsImV4cCI6MTc3MDI3OTI1NSwiaWF0IjoxNzcwMjc4OTU1LCJqdGkiOiJkNjA0MTVjOS1kMGM0LTRiNWQtYjI4My01ZmNmYjhlMDY2OGQiLCJ0b2tlbiI6ImV5SnJhV1FpT2lKa2FXUTZkMlZpT21OdmJuTjFiV1Z5TFdsa2FIVmlPblZ6WlhJNlkyOXVjM1Z0WlhJamEyVjVMVEVpTENKaGJHY2lPaUpGWkRJMU5URTVJbjAuZXlKaGRXUWlPaUprYVdRNmQyVmlPbU52Ym5OMWJXVnlMV2xrYUhWaU9uVnpaWEk2WTI5dWMzVnRaWElpTENKemRXSWlPaUprYVdRNmQyVmlPbkJ5YjNacFpHVnlMV2xrYUhWaU9uVnpaWEk2Y0hKdmRtbGtaWElpTENKdVltWWlPakUzTnpBeU56ZzVOVFFzSW5OamIzQmxJam9pYjNKbkxtVmpiR2x3YzJVdWRISmhZM1IxYzNndWRtTXVkSGx3WlRwTlpXMWlaWEp6YUdsd1EzSmxaR1Z1ZEdsaGJEcHlaV0ZrSWl3aWFYTnpJam9pWkdsa09uZGxZanBqYjI1emRXMWxjaTFwWkdoMVlqcDFjMlZ5T21OdmJuTjFiV1Z5SWl3aVpYaHdJam94Tnpjd01qYzVNalUwTENKcFlYUWlPakUzTnpBeU56ZzVOVFFzSW1wMGFTSTZJbUZqWTJWemMzUnZhMlZ1TFRjeFlUaG1OVEE1TFRnd1lUa3RORE13WkMxaU1qVTBMVE14TkdGaVlUQmtOalk1T1NKOS5pcFJwZGlfRWtoN3k0SUlxaHFMZ0hVMzVGbjdOTmt2NmU2aElMWHk4cFpPYmR5MzN5M01LcHBJNjE0MjRleUh3cXptaDdYMmt3VjJTNWdEeTNhT0tDUSJ9.42YDTnuzZ0RprqLjFw6hUoAXrgpPxyzKNFrqLdbWz6HXAiujkq32QAFU-M9gtQ0hMNcjshRZUX6DryBWxhGNDw + offerId: MQ==:YXNzZXRJZA==:MDFhN2ZjYWYtODgzOS00N2JmLTllZDAtM2Y0YjliMTFiOWM5 + negotiation-id: 3745ad50-6b99-4142-bf1a-509b3d0e313d + contractId: 3345f7f1-f735-4c92-8aa2-6e137203b2f9 + transferId: 3ebe55c6-900a-4c03-b213-20c5c3f0274d + pullSecret: eyJraWQiOiJwcm92X3B1YiIsImFsZyI6IlJTMjU2In0.eyJpc3MiOiJhbm9ueW1vdXMiLCJhdWQiOiJkaWQ6d2ViOmNvbnN1bWVyLWlkaHViOnVzZXI6Y29uc3VtZXIiLCJzdWIiOiJhbm9ueW1vdXMiLCJpYXQiOjE3NzAyNzg5ODgsImp0aSI6IjUwYWQxMjk3LWZhN2QtNDI0ZC1hNjBhLTg5M2MwMGE4OTZhYyJ9.GkSz0qXhFmqPaLQpfPLkAvODX-iekoAQvLh3Kglhm7DApNF3PsGnv-Qzm7m8eNAqTUTWB9XXkRng_XqWmuAd-FWvzwG8d7ZaAahuykkOgX1W7vHWBMdJa-zvNm0cnzm-TQLWYCU-tDSKk_g_UrDUaFf9Jdq-avCoer3wcZrEmrf0K4o_WWs-l5hZEfDIOYHRsgoCY3P8pMcZYRjV57zdLUDl9SvLuCRR0ex0fKxJ2pb7mlaCL5ooD6fRaqWyrLvrIKZaDYfwKrX7IRJT9ePKyls9VKA9JBakh676L0jBr5-2TYG3uE9Xhyv4CZlqyck-_NyiL4Jao8-lL5FVCbPDVQ + ISS_PART_CONT: did:web:example.com + CONS_PART_CONT: did:web:example.com + PROV_PART_CONT: did:web:example.com + PROVIDER_VAULTURL: {{PROVIDER_DOMAIN}} + CONSUMER_MANAGEMENT_API_KEY: prov-management-api-key + ISSUER_DOMAIN: https://example.com + CONSUMER_DOMAIN: https://example.com + PROVIDER_DOMAIN: https://example.com +} diff --git a/bruno/single-node/identities/Inspect Outcome/ShowConsumerCredentials.bru b/bruno/single-node/identities/Inspect Outcome/ShowConsumerCredentials.bru new file mode 100644 index 0000000..5886d0f --- /dev/null +++ b/bruno/single-node/identities/Inspect Outcome/ShowConsumerCredentials.bru @@ -0,0 +1,33 @@ +meta { + name: ShowConsumerCredentials + type: http + seq: 1 +} + +get { + url: {{CONSUMER_IDHUB_ID_API}}/v1alpha/credentials + body: none + auth: none +} + +headers { + x-api-key: YWRtaW4.adminKey +} + +script:pre-request { + const t = Date.now(); + await new Promise(resolve => setTimeout(resolve, 2500)); + console.log("Waited " + (Date.now() - t) + " ms"); +} + +tests { + test("Got non-empty response", function(){ + const body = res.getBody(); + expect(body).to.be.an("array").that.is.not.empty; + }) +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/identities/Inspect Outcome/ShowProviderCredentials.bru b/bruno/single-node/identities/Inspect Outcome/ShowProviderCredentials.bru new file mode 100644 index 0000000..072de2c --- /dev/null +++ b/bruno/single-node/identities/Inspect Outcome/ShowProviderCredentials.bru @@ -0,0 +1,27 @@ +meta { + name: ShowProviderCredentials + type: http + seq: 2 +} + +get { + url: {{PROVIDER_IDHUB_ID_API}}/v1alpha/credentials + body: none + auth: none +} + +headers { + x-api-key: YWRtaW4.adminKey +} + +tests { + test("Got non-empty response", function(){ + const body = res.getBody() + expect(body).to.be.an("array").that.is.not.empty; + }) +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/identities/Inspect Outcome/folder.bru b/bruno/single-node/identities/Inspect Outcome/folder.bru new file mode 100644 index 0000000..d3d8460 --- /dev/null +++ b/bruno/single-node/identities/Inspect Outcome/folder.bru @@ -0,0 +1,12 @@ +meta { + name: Inspect Outcome + seq: 4 +} + +auth { + mode: inherit +} + +docs { + Here we are taking a look at the credentials, that the trusted issuer created for the participants. +} diff --git a/bruno/single-node/identities/Prepare Consumer ID/CreateConsumerParticipant.bru b/bruno/single-node/identities/Prepare Consumer ID/CreateConsumerParticipant.bru new file mode 100644 index 0000000..2f21fc1 --- /dev/null +++ b/bruno/single-node/identities/Prepare Consumer ID/CreateConsumerParticipant.bru @@ -0,0 +1,67 @@ +meta { + name: CreateConsumerParticipant + type: http + seq: 1 +} + +post { + url: {{CONSUMER_IDHUB_ID_API}}/v1alpha/participants + body: json + auth: inherit +} + +headers { + x-api-key: YWRtaW4.adminKey +} + +body:json { + { + "roles": [], + "serviceEndpoints": [ + { + "id": "ConsumerCredentialService-ID", + "type": "CredentialService", + "serviceEndpoint": "{{CONSUMER_DOMAIN}}/api/credentials/v1/participants/{{CONS_PART_CONT}}" + }, + { + "id": "ConsumerIssuerService-ID", + "type": "IssuerService", + "serviceEndpoint": "{{CONSUMER_DOMAIN}}/api/issuance/v1alpha/participants/{{CONS_PART_CONT}}" + } + ], + "active": true, + "participantContextId": "{{CONS_PART_CONT}}", + "did": "{{CONS_ID}}", + "key": { + "keyId": "{{CONS_ID}}#key-1", + "privateKeyAlias": "{{CONS_ID}}-alias", + "keyGeneratorParams": { + "algorithm": "EdDSA", + "curve": "Ed25519" + } + } + } +} + +script:pre-request { + const cons_id = bru.getEnvVar("CONS_ID"); + //const participantContext = cons_id.split(":").slice(3).join(":").replace(/:/g, "-"); + const participantContext = cons_id + bru.setEnvVar("CONS_PART_CONT", participantContext); +} + +script:post-response { + const apiKey = res.getBody().apiKey.trim(); + if (apiKey) { + bru.setEnvVar("CONSUMER_IH_APIKEY", apiKey); + } + const stsSecret = res.getBody().clientSecret.trim(); + if (stsSecret) { + bru.setEnvVar("CONSUMER_STS_SECRET", stsSecret) + } +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/identities/Prepare Consumer ID/Get Consumer DID Doc.bru b/bruno/single-node/identities/Prepare Consumer ID/Get Consumer DID Doc.bru new file mode 100644 index 0000000..6cacadc --- /dev/null +++ b/bruno/single-node/identities/Prepare Consumer ID/Get Consumer DID Doc.bru @@ -0,0 +1,16 @@ +meta { + name: Get Consumer DID Doc + type: http + seq: 3 +} + +get { + url: {{CONSUMER_IDHUB_DID_API}}/did.json + body: none + auth: inherit +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/identities/Prepare Consumer ID/RequestConsumerDevMemCredential.bru b/bruno/single-node/identities/Prepare Consumer ID/RequestConsumerDevMemCredential.bru new file mode 100644 index 0000000..334cd78 --- /dev/null +++ b/bruno/single-node/identities/Prepare Consumer ID/RequestConsumerDevMemCredential.bru @@ -0,0 +1,35 @@ +meta { + name: RequestConsumerDevMemCredential + type: http + seq: 2 +} + +post { + url: {{CONSUMER_IDHUB_ID_API}}/v1alpha/participants/{{CONS_PART_CONT}}/credentials/request + body: json + auth: none +} + +body:json { + { + "issuerDid": "{{ISS_ID}}", + "credentials": [{ + "format": "VC1_0_JWT", + "type": "MembershipCredential", + "id": "dev-credential-def-1" + }] + } +} + +script:pre-request { + const cons_id = bru.getEnvVar("CONS_ID"); + //const participantContext = cons_id.split(":").slice(3).join(":").replace(/:/g, "-"); + const participantContext = cons_id + bru.setEnvVar("CONS_PART_CONT", participantContext); + req.setHeader("x-api-key", bru.getEnvVar("CONSUMER_IH_APIKEY")); +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/identities/Prepare Consumer ID/VaultSecret test.bru b/bruno/single-node/identities/Prepare Consumer ID/VaultSecret test.bru new file mode 100644 index 0000000..fa631b8 --- /dev/null +++ b/bruno/single-node/identities/Prepare Consumer ID/VaultSecret test.bru @@ -0,0 +1,21 @@ +meta { + name: VaultSecret test + type: http + seq: 5 +} + +get { + url: {{CONSUMER_VAULTURL}}/v1/secret/data/consumersecret + body: none + auth: inherit +} + +headers { + X-Vault-Token: vaultsecret0123456789 + ~X-Vault-Token: +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/identities/Prepare Consumer ID/VaultSecret.bru b/bruno/single-node/identities/Prepare Consumer ID/VaultSecret.bru new file mode 100644 index 0000000..b3c7266 --- /dev/null +++ b/bruno/single-node/identities/Prepare Consumer ID/VaultSecret.bru @@ -0,0 +1,29 @@ +meta { + name: VaultSecret + type: http + seq: 4 +} + +post { + url: {{CONSUMER_VAULTURL}}/v1/secret/data/consumersecret + body: json + auth: inherit +} + +headers { + X-Vault-Token: vaultsecret0123456789 + ~X-Vault-Token: +} + +body:json { + { + "data": { + "content": "{{CONSUMER_STS_SECRET}}" + } + } +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/identities/Prepare Consumer ID/folder.bru b/bruno/single-node/identities/Prepare Consumer ID/folder.bru new file mode 100644 index 0000000..e92dbb3 --- /dev/null +++ b/bruno/single-node/identities/Prepare Consumer ID/folder.bru @@ -0,0 +1,13 @@ +meta { + name: Prepare Consumer ID + seq: 2 +} + +auth { + mode: inherit +} + +docs { + The requests in this folder are necessary for creating the identity of the consumer participant. + We are doing an initial registration at the identity hub. Then we take a look at the created DID document. Then we trigger a credential request toward the trusted issuer. And also, we are storing the STS secret that the identity hub gave us, at the vault. +} diff --git a/bruno/single-node/identities/Prepare Issuer/CreateIssuerParticipant.bru b/bruno/single-node/identities/Prepare Issuer/CreateIssuerParticipant.bru new file mode 100644 index 0000000..0e0521b --- /dev/null +++ b/bruno/single-node/identities/Prepare Issuer/CreateIssuerParticipant.bru @@ -0,0 +1,63 @@ +meta { + name: CreateIssuerParticipant + type: http + seq: 1 +} + +post { + url: {{ISSUER_ID_API}}/v1alpha/participants + body: json + auth: inherit +} + +headers { + x-api-key: YWRtaW4.adminKey +} + +body:json { + { + "roles": [], + "serviceEndpoints": [ + { + "id": "IssuerIssuerService-ID", + "type": "IssuerService", + "serviceEndpoint": "{{ISSUER_DOMAIN}}/api/issuance/v1alpha/participants/{{ISS_PART_CONT}}" + }, + { + "id": "IssuerCredentialService-ID", + "type": "CredentialService", + "serviceEndpoint": "{{ISSUER_DOMAIN}}/api/credentials/v1/participants/{{ISS_PART_CONT}}" + } + ], + "active": true, + "participantContextId": "{{ISS_PART_CONT}}", + "did": "{{ISS_ID}}", + "key": { + "keyId": "{{ISS_ID}}#key-1", + "privateKeyAlias": "{{ISS_ID}}-alias", + "keyGeneratorParams": { + "algorithm": "EdDSA", + "curve": "Ed25519" + } + } + } +} + +script:pre-request { + const iss_id = bru.getEnvVar("ISS_ID"); + //const participantContext = iss_id.split(":").slice(3).join(":").replace(/:/g, "-"); + const participantContext = iss_id + bru.setEnvVar("ISS_PART_CONT", participantContext); +} + +script:post-response { + const apiKey = res.getBody().apiKey.trim(); + if (apiKey) { + bru.setEnvVar("ISSUER_APIKEY", apiKey); + } +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/identities/Prepare Issuer/Get Issuer DID Doc.bru b/bruno/single-node/identities/Prepare Issuer/Get Issuer DID Doc.bru new file mode 100644 index 0000000..8c0d744 --- /dev/null +++ b/bruno/single-node/identities/Prepare Issuer/Get Issuer DID Doc.bru @@ -0,0 +1,16 @@ +meta { + name: Get Issuer DID Doc + type: http + seq: 2 +} + +get { + url: {{ISSUER_DID_API}}/did.json + body: none + auth: inherit +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/identities/Prepare Issuer/addConsumerHolder.bru b/bruno/single-node/identities/Prepare Issuer/addConsumerHolder.bru new file mode 100644 index 0000000..17e1c8f --- /dev/null +++ b/bruno/single-node/identities/Prepare Issuer/addConsumerHolder.bru @@ -0,0 +1,33 @@ +meta { + name: addConsumerHolder + type: http + seq: 3 +} + +post { + url: {{ISSUER_ISS_API}}/v1alpha/participants/{{ISS_PART_CONT}}/holders + body: json + auth: inherit +} + +body:json { + { + "holderId" : "{{CONS_ID}}", + "did" : "{{CONS_ID}}", + "name" : "{{CONS_PART_CONT}}" + } +} + +script:pre-request { + const cons_id = bru.getEnvVar("CONS_ID"); + //const participantContext = cons_id.split(":").slice(3).join(":").replace(/:/g, "-"); + const participantContext = cons_id + bru.setEnvVar("CONS_PART_CONT", participantContext); + + req.setHeader("x-api-key", bru.getEnvVar("ISSUER_APIKEY")); +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/identities/Prepare Issuer/addProviderHolder.bru b/bruno/single-node/identities/Prepare Issuer/addProviderHolder.bru new file mode 100644 index 0000000..d3c48ec --- /dev/null +++ b/bruno/single-node/identities/Prepare Issuer/addProviderHolder.bru @@ -0,0 +1,33 @@ +meta { + name: addProviderHolder + type: http + seq: 4 +} + +post { + url: {{ISSUER_ISS_API}}/v1alpha/participants/{{ISS_PART_CONT}}/holders + body: json + auth: inherit +} + +body:json { + { + "holderId" : "{{PROV_ID}}", + "did" : "{{PROV_ID}}", + "name" : "{{PROV_PART_CONT}}" + } +} + +script:pre-request { + const prov_id = bru.getEnvVar("PROV_ID"); + //const participantContext = prov_id.split(":").slice(3).join(":").replace(/:/g, "-"); + const participantContext = prov_id + bru.setEnvVar("PROV_PART_CONT", participantContext); + + req.setHeader("x-api-key", bru.getEnvVar("ISSUER_APIKEY")); +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/identities/Prepare Issuer/createDevAttestation.bru b/bruno/single-node/identities/Prepare Issuer/createDevAttestation.bru new file mode 100644 index 0000000..1e9801e --- /dev/null +++ b/bruno/single-node/identities/Prepare Issuer/createDevAttestation.bru @@ -0,0 +1,55 @@ +meta { + name: createDevAttestation + type: http + seq: 5 +} + +post { + url: {{ISSUER_ISS_API}}/v1alpha/participants/{{ISS_PART_CONT}}/attestations + body: json + auth: none +} + +headers { + ~x-api-key: {{ISSUER_APIKEY}} +} + +body:json { + { + "attestationType": "dev", + "id": "dev-def-1", + "configuration": { + "{{CONS_ID}}": { + "isConsumer": true, + "isProvider": false, + "foo": { + "bar": 123 + } + }, + "{{PROV_ID}}": { + "isConsumer": false, + "isProvider": true, + "foo": { + "bar": 789 + } + }, + "default": { + "isConsumer": false, + "isProvider": false, + "foo": { + "bar": 0 + } + }, + "blackList": [] + } + } +} + +script:pre-request { + req.setHeader("x-api-key", bru.getEnvVar("ISSUER_APIKEY")); +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/identities/Prepare Issuer/createDevMemCredentialDef.bru b/bruno/single-node/identities/Prepare Issuer/createDevMemCredentialDef.bru new file mode 100644 index 0000000..fe36fe1 --- /dev/null +++ b/bruno/single-node/identities/Prepare Issuer/createDevMemCredentialDef.bru @@ -0,0 +1,42 @@ +meta { + name: createDevMemCredentialDef + type: http + seq: 6 +} + +post { + url: {{ISSUER_ISS_API}}/v1alpha/participants/{{ISS_PART_CONT}}/credentialdefinitions + body: json + auth: inherit +} + +body:json { + { + "attestations": [ + "dev-def-1" + ], + "credentialType": "MembershipCredential", + "id": "dev-credential-def-1", + "jsonSchema": "{}", + "jsonSchemaUrl": "https://example.com/schema/dev-credential.json", + "mappings": [ + { + "input": "content", + "output": "credentialSubject", + "required": true + } + ], + "rules": [], + "format": "VC1_0_JWT", + "validity": 15552000 + } +} + +script:pre-request { + req.setHeader("x-api-key", bru.getEnvVar("ISSUER_APIKEY")); +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/identities/Prepare Issuer/folder.bru b/bruno/single-node/identities/Prepare Issuer/folder.bru new file mode 100644 index 0000000..ddc334f --- /dev/null +++ b/bruno/single-node/identities/Prepare Issuer/folder.bru @@ -0,0 +1,22 @@ +meta { + name: Prepare Issuer + seq: 1 +} + +auth { + mode: inherit +} + +docs { + This folder contains the initial steps for setting up our own dataspace. First, we need to define the participant that is universally trusted by all regular dataspace members, the so-called "trusted issuer". + + First we register him under his own did:web id at the issuer service host. + + Then we will announce the existence of other regular members. This is done in the "addXXXHolder" requests. + + Then we have to tell to issuer participant that there shall be membership credentials, which can be handed out to the entities, which we had announced as holders. + + Since the primary motivation for this collection is not to be a guide for handling the administration of data space issuers, the details of the "createAttestation" and "createCredentialDef" requests don't matter much at this point. It suffices to say that they are technically required to enable the credential issuance process. + + +} diff --git a/bruno/single-node/identities/Prepare Provider ID/CreateProviderParticipant.bru b/bruno/single-node/identities/Prepare Provider ID/CreateProviderParticipant.bru new file mode 100644 index 0000000..daee4c9 --- /dev/null +++ b/bruno/single-node/identities/Prepare Provider ID/CreateProviderParticipant.bru @@ -0,0 +1,67 @@ +meta { + name: CreateProviderParticipant + type: http + seq: 1 +} + +post { + url: {{PROVIDER_IDHUB_ID_API}}/v1alpha/participants + body: json + auth: inherit +} + +headers { + x-api-key: YWRtaW4.adminKey +} + +body:json { + { + "roles": [], + "serviceEndpoints": [ + { + "id": "ProviderCredentialService-ID", + "type": "CredentialService", + "serviceEndpoint": "{{PROVIDER_DOMAIN}}/api/credentials/v1/participants/{{PROV_PART_CONT}}" + }, + { + "id": "ProviderIssuerService-ID", + "type": "IssuerService", + "serviceEndpoint": "{{PROVIDER_DOMAIN}}/api/issuance/v1alpha/participants/{{PROV_PART_CONT}}" + } + ], + "active": true, + "participantContextId": "{{PROV_PART_CONT}}", + "did": "{{PROV_ID}}", + "key": { + "keyId": "{{PROV_ID}}#key-1", + "privateKeyAlias": "{{PROV_ID}}-alias", + "keyGeneratorParams": { + "algorithm": "EdDSA", + "curve": "Ed25519" + } + } + } +} + +script:pre-request { + const prov_id = bru.getEnvVar("PROV_ID"); + //const participantContext = prov_id.split(":").slice(3).join(":").replace(/:/g, "-"); + const participantContext = prov_id + bru.setEnvVar("PROV_PART_CONT", participantContext); +} + +script:post-response { + const apiKey = res.getBody().apiKey.trim(); + if (apiKey) { + bru.setEnvVar("PROVIDER_IH_APIKEY", apiKey); + } + const stsSecret = res.getBody().clientSecret.trim(); + if (stsSecret) { + bru.setEnvVar("PROVIDER_STS_SECRET", stsSecret) + } +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/identities/Prepare Provider ID/Get Provider DID Doc.bru b/bruno/single-node/identities/Prepare Provider ID/Get Provider DID Doc.bru new file mode 100644 index 0000000..1ac06f2 --- /dev/null +++ b/bruno/single-node/identities/Prepare Provider ID/Get Provider DID Doc.bru @@ -0,0 +1,16 @@ +meta { + name: Get Provider DID Doc + type: http + seq: 3 +} + +get { + url: {{PROVIDER_IDHUB_DID_API}} + body: none + auth: inherit +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/identities/Prepare Provider ID/RequestProviderDevMemCredential.bru b/bruno/single-node/identities/Prepare Provider ID/RequestProviderDevMemCredential.bru new file mode 100644 index 0000000..d90a44a --- /dev/null +++ b/bruno/single-node/identities/Prepare Provider ID/RequestProviderDevMemCredential.bru @@ -0,0 +1,36 @@ +meta { + name: RequestProviderDevMemCredential + type: http + seq: 2 +} + +post { + url: {{PROVIDER_IDHUB_ID_API}}/v1alpha/participants/{{PROV_PART_CONT}}/credentials/request + body: json + auth: none +} + +body:json { + { + "issuerDid": "{{ISS_ID}}", + "credentials": [{ + "format": "VC1_0_JWT", + "type": "MembershipCredential", + "id": "dev-credential-def-1" + }] + } +} + +script:pre-request { + const prov_id = bru.getEnvVar("PROV_ID"); + // const participantContext = prov_id.split(":").slice(3).join(":").replace(/:/g, "-"); + const participantContext = prov_id + bru.setEnvVar("PROV_PART_CONT", participantContext); + + req.setHeader("x-api-key", bru.getEnvVar("PROVIDER_IH_APIKEY")); +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/identities/Prepare Provider ID/VaultSecret test.bru b/bruno/single-node/identities/Prepare Provider ID/VaultSecret test.bru new file mode 100644 index 0000000..8cf7cbd --- /dev/null +++ b/bruno/single-node/identities/Prepare Provider ID/VaultSecret test.bru @@ -0,0 +1,21 @@ +meta { + name: VaultSecret test + type: http + seq: 5 +} + +get { + url: {{PROVIDER_VAULTURL}}/v1/secret/data/providersecret + body: none + auth: inherit +} + +headers { + X-Vault-Token: vaultsecret0123456789 + ~X-Vault-Token: +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/identities/Prepare Provider ID/VaultSecret.bru b/bruno/single-node/identities/Prepare Provider ID/VaultSecret.bru new file mode 100644 index 0000000..806c7c0 --- /dev/null +++ b/bruno/single-node/identities/Prepare Provider ID/VaultSecret.bru @@ -0,0 +1,29 @@ +meta { + name: VaultSecret + type: http + seq: 4 +} + +post { + url: {{PROVIDER_VAULTURL}}/v1/secret/data/providersecret + body: json + auth: inherit +} + +headers { + X-Vault-Token: vaultsecret0123456789 + ~X-Vault-Token: +} + +body:json { + { + "data": { + "content": "{{PROVIDER_STS_SECRET}}" + } + } +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/identities/Prepare Provider ID/folder.bru b/bruno/single-node/identities/Prepare Provider ID/folder.bru new file mode 100644 index 0000000..59be317 --- /dev/null +++ b/bruno/single-node/identities/Prepare Provider ID/folder.bru @@ -0,0 +1,13 @@ +meta { + name: Prepare Provider ID + seq: 3 +} + +auth { + mode: inherit +} + +docs { + The requests in this folder are necessary for creating the identity of the provider participant. + We are doing an initial registration at the identity hub. Then we take a look at the created DID document. Then we trigger a credential request toward the trusted issuer. And also, we are storing the STS secret that the identity hub gave us, at the vault. +} diff --git a/bruno/single-node/identities/Simulated DCP Flow/Consumer Token.bru b/bruno/single-node/identities/Simulated DCP Flow/Consumer Token.bru new file mode 100644 index 0000000..16b2325 --- /dev/null +++ b/bruno/single-node/identities/Simulated DCP Flow/Consumer Token.bru @@ -0,0 +1,35 @@ +meta { + name: Consumer Token + type: http + seq: 1 +} + +post { + url: {{CONSUMER_IDHUB_STS_API}}/token + body: formUrlEncoded + auth: inherit +} + +body:form-urlencoded { + grant_type: client_credentials + client_secret: {{CONSUMER_STS_SECRET}} + client_id: {{CONS_ID}} + audience: {{PROV_ID}} + bearer_access_scope: org.eclipse.dspace.dcp.vc.type:MembershipCredential:read +} + +script:post-response { + const atob = require("atob"); + const accessToken = res.getBody().access_token.trim(); + const parts = accessToken.split("."); + const payload = atob(parts[1]); + const payloadObject = JSON.parse(payload); + const internalToken = payloadObject.token.trim(); + + bru.setEnvVar("cons_access_token", internalToken); +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/identities/Simulated DCP Flow/Get Credential.bru b/bruno/single-node/identities/Simulated DCP Flow/Get Credential.bru new file mode 100644 index 0000000..8ea42d7 --- /dev/null +++ b/bruno/single-node/identities/Simulated DCP Flow/Get Credential.bru @@ -0,0 +1,47 @@ +meta { + name: Get Credential + type: http + seq: 3 +} + +post { + url: {{CONSUMER_IDHUB_CREDS_API}}/v1/participants/{{CONS_PART_CONT}}/presentations/query + body: json + auth: bearer +} + +auth:bearer { + token: {{prov_access_token}} +} + +body:json { + { + "@context": [ + "https://w3id.org/dspace-dcp/v1.0/dcp.jsonld", + "https://identity.foundation/presentation-exchange/submission/v1" + ], + "type": "PresentationQueryMessage", + "presentationDefinition": null, + "scope": [ + "org.eclipse.dspace.dcp.vc.type:MembershipCredential:read" + ] + } +} + +tests { + test("Contains VerifiableCredential", function(){ + const atob = require("atob"); + const presentation = res.getBody().presentation[0]; + const decodedPayload = JSON.parse(atob(presentation.split(".")[1])); + + const verifiableCred = atob(decodedPayload.vp.verifiableCredential[0].split(".")[1]); + + const success = verifiableCred.includes("VerifiableCredential") + expect(success); + }) +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/identities/Simulated DCP Flow/Provider Token.bru b/bruno/single-node/identities/Simulated DCP Flow/Provider Token.bru new file mode 100644 index 0000000..3ec92f6 --- /dev/null +++ b/bruno/single-node/identities/Simulated DCP Flow/Provider Token.bru @@ -0,0 +1,30 @@ +meta { + name: Provider Token + type: http + seq: 2 +} + +post { + url: {{PROVIDER_IDHUB_STS_API}}/token + body: formUrlEncoded + auth: inherit +} + +body:form-urlencoded { + grant_type: client_credentials + client_secret: {{PROVIDER_STS_SECRET}} + client_id: {{PROV_ID}} + audience: {{CONS_ID}} + token: {{cons_access_token}} +} + +script:post-response { + const accessToken = res.getBody().access_token.trim(); + + bru.setEnvVar("prov_access_token", accessToken); +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/identities/Simulated DCP Flow/folder.bru b/bruno/single-node/identities/Simulated DCP Flow/folder.bru new file mode 100644 index 0000000..5e25d16 --- /dev/null +++ b/bruno/single-node/identities/Simulated DCP Flow/folder.bru @@ -0,0 +1,34 @@ +meta { + name: Simulated DCP Flow + seq: 5 +} + +auth { + mode: inherit +} + +docs { + This section is meant to show in principle, what happens during a DCP protocol validated interaction between two controlplanes. It also serves as a final test. If these requests do succeed, then we can be sure that all previous steps went well. + + Let's assume that the consumer intends to obtain the DSP catolog from the provider. + Then the consumer will request a self signed SI token from his own Identity-Hub's secure token service (STS), see the "Consumer Token" request. + + In that request body, the consumer informs the STS about the intended audience and the credential type he wants to show to the other side. + + In the request body, we should receive an access token in JWT format, the "consumer-access-token". + + Please feel free to decode the "consumer-access-token" with a tool of your choice and observe that token's payload. You will find, that this payload itself contains another JWT inside the "token" claim. + + The entire "consumer-access-token" will now be sent by the consumer-side-EDC to the provider-side-EDC via the "Authentication" header of a request to the according DSP-catolog request api endpoint. Since the "consumer-access-token" is signed with the consumer private key, the provider can now download the consumer's DID document, read the consumer's public key and use it to check that the JWT's signature is valid. + + We are not doing the signature check here in this small simulation, so let's just assume that it turned out positive. + + Now the provider wants to see, which credentials the consumer is going to show him. For that, he needs to retrieve it from the consumer's credential service. The URL can be found in the consumer's DID document. + + But first, he needs to talk to his own secure token service (STS). So he is unwrapping the "token" claim and sending it to his own STS, see the "Post Request Script" of the "Consumer Token" request and the request body in the "Provider Token" request. + + The response of the provider's STS will contain another access token, we are calling it "provider access token". This "provider access token" can now be attached as an "authorization" header to the provider's request to the consumer's credential service. + + The response of the consumer credential service contains the verifiable presentation, which itself now contains the verfiable credential, which the trusted issuer initially handed out to the consumer. + +} diff --git a/bruno/single-node/identities/folder.bru b/bruno/single-node/identities/folder.bru new file mode 100644 index 0000000..9b98e35 --- /dev/null +++ b/bruno/single-node/identities/folder.bru @@ -0,0 +1,8 @@ +meta { + name: identities + seq: 1 +} + +auth { + mode: inherit +} diff --git a/bruno/single-node/other/RevokeCred.bru b/bruno/single-node/other/RevokeCred.bru new file mode 100644 index 0000000..059dddd --- /dev/null +++ b/bruno/single-node/other/RevokeCred.bru @@ -0,0 +1,20 @@ +meta { + name: RevokeCred + type: http + seq: 2 +} + +post { + url: {{ISSUER_ISS_API}}/v1alpha/participants/{{ISS_PART_CONT}}/credentials/{{credentialId}}/revoke + body: none + auth: inherit +} + +headers { + x-api-key: YWRtaW4.adminKey +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/other/Version.bru b/bruno/single-node/other/Version.bru new file mode 100644 index 0000000..d219789 --- /dev/null +++ b/bruno/single-node/other/Version.bru @@ -0,0 +1,20 @@ +meta { + name: Version + type: http + seq: 7 +} + +get { + url: http://localhost:29020/dsp/.well-known/dspace-version + body: none + auth: inherit +} + +headers { + Accept: application/json +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/other/folder.bru b/bruno/single-node/other/folder.bru new file mode 100644 index 0000000..70b6b92 --- /dev/null +++ b/bruno/single-node/other/folder.bru @@ -0,0 +1,8 @@ +meta { + name: other + seq: 3 +} + +auth { + mode: inherit +} diff --git a/bruno/single-node/transactions/consumer/CheckNegotiationResult.bru b/bruno/single-node/transactions/consumer/CheckNegotiationResult.bru new file mode 100644 index 0000000..17551cb --- /dev/null +++ b/bruno/single-node/transactions/consumer/CheckNegotiationResult.bru @@ -0,0 +1,31 @@ +meta { + name: CheckNegotiationResult + type: http + seq: 3 +} + +get { + url: {{CONSUMER_MANAGEMENT}}/v3/contractnegotiations/{{negotiation-id}} + body: none + auth: apikey +} + +headers { + Accept: application/json +} + +auth:apikey { + key: X-Api-key + value: {{CONSUMER_MANAGEMENT_API_KEY}} + placement: header +} + +script:post-response { + const contractId = res.getBody()['contractAgreementId']; + bru.setEnvVar("contractId", contractId); +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/transactions/consumer/Get EDR.bru b/bruno/single-node/transactions/consumer/Get EDR.bru new file mode 100644 index 0000000..8c282a2 --- /dev/null +++ b/bruno/single-node/transactions/consumer/Get EDR.bru @@ -0,0 +1,31 @@ +meta { + name: Get EDR + type: http + seq: 5 +} + +get { + url: {{CONSUMER_MANAGEMENT}}/v3/edrs/{{transferId}}/dataaddress + body: none + auth: apikey +} + +headers { + Accept: application/json +} + +auth:apikey { + key: X-Api-key + value: {{CONSUMER_MANAGEMENT_API_KEY}} + placement: header +} + +script:post-response { + const authToken = res.getBody().authorization; + bru.setEnvVar("pullSecret", authToken); +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/transactions/consumer/InitPullTransfer.bru b/bruno/single-node/transactions/consumer/InitPullTransfer.bru new file mode 100644 index 0000000..72e0a18 --- /dev/null +++ b/bruno/single-node/transactions/consumer/InitPullTransfer.bru @@ -0,0 +1,41 @@ +meta { + name: InitPullTransfer + type: http + seq: 4 +} + +post { + url: {{CONSUMER_MANAGEMENT}}/v3/transferprocesses + body: json + auth: apikey +} + +auth:apikey { + key: X-Api-key + value: {{CONSUMER_MANAGEMENT_API_KEY}} + placement: header +} + +body:json { + { + "@context": { + "edc": "https://w3id.org/edc/v0.0.1/ns/" + }, + "@type": "TransferRequestDto", + "protocol": "dataspace-protocol-http:2025-1", + "contractId": "{{contractId}}", + "counterPartyAddress": "{{PROVIDER_DOMAIN}}/dsp/2025-1", + "connectorId": "{{PROV_ID}}", + "transferType": "HttpData-PULL" + } +} + +script:post-response { + const transferId = res.getBody()['@id']; + bru.setEnvVar("transferId", transferId); +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/transactions/consumer/InitiateNegotiation.bru b/bruno/single-node/transactions/consumer/InitiateNegotiation.bru new file mode 100644 index 0000000..b9c112f --- /dev/null +++ b/bruno/single-node/transactions/consumer/InitiateNegotiation.bru @@ -0,0 +1,53 @@ +meta { + name: InitiateNegotiation + type: http + seq: 2 +} + +post { + url: {{CONSUMER_MANAGEMENT}}/v3/contractnegotiations + body: json + auth: apikey +} + +headers { + Accept: application/json +} + +auth:apikey { + key: X-Api-key + value: {{CONSUMER_MANAGEMENT_API_KEY}} + placement: header +} + +body:json { + { + "@context": { + "@vocab": "https://w3id.org/edc/v0.0.1/ns/", + "odrl": "http://www.w3.org/ns/odrl/2/" + }, + "@type": "ContractRequest", + "counterPartyAddress": "{{PROVIDER_DOMAIN}}/dsp/2025-1", + "connectorId": "{{PROV_ID}}", + "protocol": "dataspace-protocol-http:2025-1", + "policy": { + "@context": "http://www.w3.org/ns/odrl.jsonld", + "@id": "{{offerId}}", + "@type": "Offer", + "assigner": "{{PROV_ID}}", + "assignee": "{{CONS_ID}}", + "target": "assetId" + } + } +} + +script:post-response { + var x = res.getBody()['@id']; + console.log("id " + x); + bru.setEnvVar("negotiation-id", res.getBody()['@id']); +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/transactions/consumer/PullAssetData.bru b/bruno/single-node/transactions/consumer/PullAssetData.bru new file mode 100644 index 0000000..df33451 --- /dev/null +++ b/bruno/single-node/transactions/consumer/PullAssetData.bru @@ -0,0 +1,20 @@ +meta { + name: PullAssetData + type: http + seq: 6 +} + +get { + url: {{PROVIDER_DATAPLANE_PUBLIC}} + body: none + auth: inherit +} + +script:pre-request { + req.setHeader("Authorization", bru.getEnvVar("pullSecret")); +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/transactions/consumer/RequestProviderCatalog.bru b/bruno/single-node/transactions/consumer/RequestProviderCatalog.bru new file mode 100644 index 0000000..a603158 --- /dev/null +++ b/bruno/single-node/transactions/consumer/RequestProviderCatalog.bru @@ -0,0 +1,47 @@ +meta { + name: RequestProviderCatalog + type: http + seq: 1 +} + +post { + url: {{CONSUMER_MANAGEMENT}}/v3/catalog/request + body: json + auth: apikey +} + +auth:apikey { + key: X-Api-key + value: {{CONSUMER_MANAGEMENT_API_KEY}} + placement: header +} + +body:json { + { + "@context": { + "@vocab": "https://w3id.org/edc/v0.0.1/ns/" + }, + "counterPartyAddress": "{{PROVIDER_DOMAIN}}/dsp/2025-1", + "counterPartyId": "{{PROV_ID}}", + "protocol": "dataspace-protocol-http:2025-1" + } +} + +script:post-response { + const offerArray = res.getBody().dataset[0].hasPolicy; + var offerId; + res.getBody().dataset[0].hasPolicy.forEach(item => { + const type = item['@type']; + const id = item['@id']; + if (type != null && type == "Offer" && id != null) { + offerId = id; + } + }); + + bru.setEnvVar("offerId", offerId); +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/transactions/consumer/folder.bru b/bruno/single-node/transactions/consumer/folder.bru new file mode 100644 index 0000000..1ef94a8 --- /dev/null +++ b/bruno/single-node/transactions/consumer/folder.bru @@ -0,0 +1,24 @@ +meta { + name: consumer + seq: 2 +} + +headers { + x-api-key: cons-management-api-key +} + +auth { + mode: inherit +} + +docs { + Here, we are taking the role of the consumer participant. + + First, we inspect the providers catalog. There we should find the asset, that was prepared in the previous stage. + + Then we trigger a negotiation process, and check its (hopefully positive) outcome. + + After that, we initiate a transfer process based on the previously negotiated contract. In the following step, we retrieve the authorization token, which the provider will give us. + + And finally, we are using that token to get access to the data, that was placed inside the provider's asset. +} diff --git a/bruno/single-node/transactions/folder.bru b/bruno/single-node/transactions/folder.bru new file mode 100644 index 0000000..d3bae9f --- /dev/null +++ b/bruno/single-node/transactions/folder.bru @@ -0,0 +1,11 @@ +meta { + name: transactions +} + +auth { + mode: inherit +} + +docs { + This section showcases the typical negotiation and transfer flows between EDC connectors. +} diff --git a/bruno/single-node/transactions/provider/CreateAsset.bru b/bruno/single-node/transactions/provider/CreateAsset.bru new file mode 100644 index 0000000..df3fea6 --- /dev/null +++ b/bruno/single-node/transactions/provider/CreateAsset.bru @@ -0,0 +1,39 @@ +meta { + name: CreateAsset + type: http + seq: 1 +} + +post { + url: {{PROVIDER_MANAGEMENT}}/v3/assets + body: json + auth: inherit +} + +body:json { + { + "@context": { + "@vocab": "https://w3id.org/edc/v0.0.1/ns/" + }, + "@id": "assetId", + "properties": { + "name": "product description", + "contenttype": "application/json" + }, + "dataAddress": { + "type": "HttpData", + "name": "Test asset", + "baseUrl": "https://jsonplaceholder.typicode.com/users", + "proxyPath": "true", + "proxyMethod": "true", + "proxyBody": "true", + "authKey": "x-api-key", + "authCode": "someAuthCode" + } + } +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/transactions/provider/CreateContractDefinition.bru b/bruno/single-node/transactions/provider/CreateContractDefinition.bru new file mode 100644 index 0000000..e7b3b06 --- /dev/null +++ b/bruno/single-node/transactions/provider/CreateContractDefinition.bru @@ -0,0 +1,28 @@ +meta { + name: CreateContractDefinition + type: http + seq: 3 +} + +post { + url: {{PROVIDER_MANAGEMENT}}/v3/contractdefinitions + body: json + auth: inherit +} + +body:json { + { + "@context": { + "@vocab": "https://w3id.org/edc/v0.0.1/ns/" + }, + "@id": "1", + "accessPolicyId": "aPolicy", + "contractPolicyId": "aPolicy", + "assetsSelector": [] + } +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/transactions/provider/CreatePolicy.bru b/bruno/single-node/transactions/provider/CreatePolicy.bru new file mode 100644 index 0000000..ede9c2a --- /dev/null +++ b/bruno/single-node/transactions/provider/CreatePolicy.bru @@ -0,0 +1,33 @@ +meta { + name: CreatePolicy + type: http + seq: 2 +} + +post { + url: {{PROVIDER_MANAGEMENT}}/v3/policydefinitions + body: json + auth: inherit +} + +body:json { + { + "@context": { + "@vocab": "https://w3id.org/edc/v0.0.1/ns/", + "odrl": "http://www.w3.org/ns/odrl/2/" + }, + "@id": "aPolicy", + "policy": { + "@context": "http://www.w3.org/ns/odrl.jsonld", + "@type": "Set", + "permission": [], + "prohibition": [], + "obligation": [] + } + } +} + +settings { + encodeUrl: true + timeout: 0 +} diff --git a/bruno/single-node/transactions/provider/folder.bru b/bruno/single-node/transactions/provider/folder.bru new file mode 100644 index 0000000..3a2cc52 --- /dev/null +++ b/bruno/single-node/transactions/provider/folder.bru @@ -0,0 +1,16 @@ +meta { + name: provider + seq: 1 +} + +headers { + x-api-key: prov-management-api-key +} + +auth { + mode: inherit +} + +docs { + In this section we are creating a simple data asset on the provider side, i.e. we register an asset, create a policy- and a contract definition. +} diff --git a/docker/single-node/.env.example b/docker/single-node/.env.example new file mode 100644 index 0000000..fa2a3d3 --- /dev/null +++ b/docker/single-node/.env.example @@ -0,0 +1,7 @@ +EMAIL= +DOMAIN= +ISSUER_DOMAIN= + +DOMAIN_MISSING_MESSAGE="Domain must be set in the .env file" + +VAULT_TOKEN= \ No newline at end of file diff --git a/docker/single-node/README.md b/docker/single-node/README.md index 51faaf0..6a96548 100644 --- a/docker/single-node/README.md +++ b/docker/single-node/README.md @@ -1,4 +1,140 @@ # Single Node (Docker) -Minimal Docker Compose setup that starts a single Connector and a single Wallet. Thi is the smallest +Minimal Docker Compose setup that starts a single Connector and a single Wallet. This is the smallest deployment for a participant to run and test their own node. + +## Prerequisites + +Make sure you have... +- ...docker installed on your machine (recommended: version>25.0.4) +- ...a domain for your IP-address +- ...copied [.env.example](./.env.example) to `.env` and changed the secrets +- ...the necessary docker images from [controlplane](https://github.com/project-construct-x/constructx-edc/pkgs/container/con-x-controlplane-postgresql-hashicorp-vault), [dataplane](https://github.com/project-construct-x/constructx-edc/pkgs/container/con-x-dataplane-postgresql-hashicorp-vault), [wallet](https://github.com/project-construct-x/wallet/pkgs/container/wallet) + - wallet + - controlplane + - dataplane + - Postgres DB + - HashiCorp Vault + + +The domain and a valid email must be set in the [.env-file](./.env): + +``` +EMAIL= +DOMAIN= +ISSUER_DOMAIN= +``` + + +## Steps +### Traefik + +#### Create Network + +First run the command `docker network create proxy` + +Sample output: +``` +35c1364363795... +``` + +#### Start Traefik + +Run the following command from the current folder to start the traefik container: +```bash +docker compose -f ./traefik/traefik-compose.yaml --env-file ./.env up -d +``` + +Wait 30 seconds before proceeding with the next steps. + +Sample output: +``` +[+] Running 1/1 +✔ Container traefik Created +``` + +## EDC in Memory + +### Start EDC-Services in Memory + +Run `docker compose -f ./connector/docker-compose-memory.yaml --env-file ./.env up -d` + +Sample output: +``` +[+] Running 7/7 +✔ Network network Created +✔ vault Healthy +✔ postgres Healthy +✔ idhub Created +✔ vault-init Exited +✔ dataplane Created +✔ controlplane Created +``` + + +### Stop and Remove in Memory + +1. `docker compose -f ./traefik/traefik-compose.yaml down` +2. `docker compose -f ./connector/docker-compose-memory.yaml --env-file ./.env down -v` +3. `docker network rm proxy` + +## EDC + +### Initialize Vault (only once) + +`docker compose -f ./connector/docker-compose.yaml --env-file ./.env up shared-vault -d` + +#### Set the appropriate ownership +The default Vault user inside the Container has the UID `100`. + +`sudo chown -R 100:100 ./connector/vault/data` + +#### Open a Terminal inside the Container + +`docker exec -it shared-vault sh` + +Run the following command inside the vault container: + +`vault operator init -key-shares=1 -key-threshold=1` + +Save the unseal key and the root token. Set the root token in the [.env](./.env) file: + +```VAULT_TOKEN=``` + +#### Unseal Vault +Run the following command with the unseal key from the previous step. + +`vault operator unseal ` + +#### Log in with the root token + +`export VAULT_TOKEN=` + +`vault login` + +#### Enable secrets +`vault secrets enable -path=secret kv-v2` + +#### Stop Vault + +`docker compose -f ./connector/docker-compose.yaml --env-file ./.env down shared-vault -v` + +Your Vault is now initialized. + +### Start EDC-Services +`docker compose -f ./connector/docker-compose.yaml --env-file ./.env up -d` + +#### Open a Terminal inside the Container + +`docker exec -it shared-vault sh` + +#### Unseal Vault +Run the following command with the unseal key. + +`vault operator unseal ` + + +### Stop and Remove +1. `docker compose -f ./traefik/traefik-compose.yaml --env-file ./.env down` +2. `docker compose -f ./connector/docker-compose.yaml --env-file ./.env down -v` +3. `docker network rm proxy` \ No newline at end of file diff --git a/docker/single-node/connector/additional_config/logging.properties b/docker/single-node/connector/additional_config/logging.properties new file mode 100644 index 0000000..5c9a7fb --- /dev/null +++ b/docker/single-node/connector/additional_config/logging.properties @@ -0,0 +1,18 @@ +handlers = java.util.logging.ConsoleHandler + +# Console Handler Config + +java.util.logging.ConsoleHandler.formatter = org.eclipse.tractusx.identityhub.monitor.ColorfulFormatter +java.util.logging.ConsoleHandler.level = FINE + +# Root level und Package-level + +.level = INFO +jakarta.json.level = OFF +jdk.event.level = OFF +okhttp3.internal.level = OFF +org.eclipse.edc.level = FINE +org.flywaydb.level = OFF +org.glassfish.level = OFF +org.jvnet.level = OFF +org.postgresql.level = OFF \ No newline at end of file diff --git a/docker/single-node/connector/additional_config/pg_init/pg_init.sql b/docker/single-node/connector/additional_config/pg_init/pg_init.sql new file mode 100644 index 0000000..c9d2ec8 --- /dev/null +++ b/docker/single-node/connector/additional_config/pg_init/pg_init.sql @@ -0,0 +1,4 @@ + CREATE DATABASE prov_ih_db; + CREATE DATABASE prov_cpl; + CREATE DATABASE prov_dpl; + diff --git a/docker/single-node/connector/additional_config/vault-init.sh b/docker/single-node/connector/additional_config/vault-init.sh new file mode 100644 index 0000000..368505c --- /dev/null +++ b/docker/single-node/connector/additional_config/vault-init.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash + +# +# Copyright (c) 2026 Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V. (represented by Fraunhofer ISST) +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# 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. +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +VAULT="${VAULT_ADDR:-http://shared-vault:8200}" +TOKEN="${VAULT_TOKEN:?missing VAULT_TOKEN}" + +# function that creates and deploys a rsa keypair: + +create_and_store_keypair() { + local prefix=$1 + + # create rsa keypair + openssl genrsa -out /tmp/${prefix}_priv_pkcs1.pem 2048 + openssl pkcs8 -topk8 -nocrypt -in /tmp/${prefix}_priv_pkcs1.pem -out /tmp/${prefix}_priv.pem + openssl rsa -in /tmp/${prefix}_priv_pkcs1.pem -pubout -out /tmp/${prefix}_pub.pem + + # deploy secrets to vault + jq -n --rawfile content /tmp/${prefix}_priv.pem '{data:{content:$content}}' | \ + curl -fsS -H "X-Vault-Token: $TOKEN" -H "Content-Type: application/json" \ + -X POST --data-binary @- "$VAULT/v1/secret/data/${prefix}_priv" + + jq -n --rawfile content /tmp/${prefix}_pub.pem '{data:{content:$content}}' | \ + curl -fsS -H "X-Vault-Token: $TOKEN" -H "Content-Type: application/json" \ + -X POST --data-binary @- "$VAULT/v1/secret/data/${prefix}_pub" + + # cleanup temp files + rm -f /tmp/${prefix}_priv_pkcs1.pem /tmp/${prefix}_priv.pem /tmp/${prefix}_pub.pem +} + +# create keypair for consumer and provider dataplane: + +create_and_store_keypair "prov" + +create_and_store_aes_key() { + local prefix=$1 + local aes_key + + # AES-Key erzeugen + aes_key="$(openssl rand -base64 32 | tr -d '\n')" + + # write AES-Key to vault, bind path to prefix + jq -n --arg content "$aes_key" '{data:{content:$content}}' | \ + curl -sSf \ + -H "X-Vault-Token: $TOKEN" \ + -H "Content-Type: application/json" \ + -X POST \ + --data-binary @- \ + "$VAULT/v1/secret/data/${prefix}-aes-key-alias" \ + || { echo "Failed to create aes key entry for ${prefix}"; exit 1; } + + echo "AES key stored at secret/data/${prefix}-aes-key-alias" +} + +# create AES keys for wallets +create_and_store_aes_key "provider-wallet" \ No newline at end of file diff --git a/docker/single-node/connector/docker-compose-memory.yaml b/docker/single-node/connector/docker-compose-memory.yaml new file mode 100644 index 0000000..dd3e9f1 --- /dev/null +++ b/docker/single-node/connector/docker-compose-memory.yaml @@ -0,0 +1,240 @@ +# +# Copyright (c) 2026 Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V. (represented by Fraunhofer ISST) +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# 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. +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +services: + shared-postgres: + container_name: shared-postgres + image: postgres:16.4-alpine + environment: + - POSTGRES_USER=admin + - POSTGRES_PASSWORD=password + volumes: + - ./additional_config/pg_init:/docker-entrypoint-initdb.d + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -h 127.0.0.1 || exit 1"] + interval: 3s + timeout: 3s + retries: 20 + networks: + - con-x-test-network + + shared-vault: + container_name: shared-vault + image: vault:1.13.3 + command: server -dev -dev-root-token-id=vaultsecret0123456789 -dev-listen-address=0.0.0.0:8200 + environment: + VAULT_ADDR: http://0.0.0.0:8200 + SKIP_SETCAP: "true" + SKIP_CHOWN: "true" + healthcheck: + test: ["CMD", "sh", "-c", "VAULT_ADDR=http://127.0.0.1:8200 vault status >/dev/null 2>&1"] + interval: 4s + timeout: 3s + retries: 20 + ports: + - "8200:8200" + networks: + - con-x-test-network + - proxy + + vault-init: + container_name: vault-init + image: alpine:3.19 + depends_on: + shared-vault: + condition: service_healthy + environment: + VAULT_ADDR: http://shared-vault:8200 + VAULT_TOKEN: vaultsecret0123456789 + volumes: + - ./additional_config/vault-init.sh:/scripts/init.sh:ro + + entrypoint: [ + "sh", "-c", + "apk add --no-check-certificate --no-cache curl jq openssl \ + && tr -d '\r' < /scripts/init.sh > /tmp/init.sh \ + && sh /tmp/init.sh" + ] + restart: "no" + networks: + - con-x-test-network + + provider-wallet: + container_name: provider-wallet + image: ghcr.io/project-construct-x/wallet:0.17.0-1 + pull_policy: missing + depends_on: + shared-postgres: + condition: service_healthy + vault-init: + condition: service_completed_successfully + ports: + - "1046:1045" # debugger + - "21000:80" # did API -> / + - "21100:15151" # identity API -> /api/identity + - "21500:9292" # sts API -> /api/sts + - "21600:13131" # credentials API -> /api/credentials + # - "8181:8181" # default API -> /api + # - "9999:9999" # statuslist API -> /statuslist + environment: + - JAVA_TOOL_OPTIONS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:1045 + - EDC_HOSTNAME=${DOMAIN} + - EDC_IAM_DID_WEB_USE_HTTPS=true + - EDC_ISSUER_ISSUANCE_SEND_RETRY_LIMIT=0 + - EDC_IAM_CREDENTIAL_RENEWAL_GRACEPERIOD=172800 + - EDC_IH_API_SUPERUSER_ID=admin + - EDC_IH_API_KEY_SUPERUSER=YWRtaW4.adminKey + - EDC_ISSUER_STATUSLIST_SIGNING_KEY_ALIAS=foo + - EDC_ENCRYPTION_AES_KEY_ALIAS=provider-wallet-aes-key-alias + - EDC_IAM_KEY_ALGORITHM=RSA + - EDC_IH_API_SUPERUSER_PUBLIC_KEY_ALIAS=admin3#pubkey + - EDC_IH_API_SUPERUSER_PRIVATE_KEY_ALIAS=admin3#privkey + - WEB_HTTP_DID_PORT=80 + - EDC_SQL_SCHEMA_AUTOCREATE=true + - EDC_DATASOURCE_DEFAULT_URL=jdbc:postgresql://shared-postgres:5432/prov_ih_db + - EDC_DATASOURCE_DEFAULT_USER=admin + - EDC_DATASOURCE_DEFAULT_PASSWORD=password + - EDC_VAULT_HASHICORP_URL=http://shared-vault:8200 + - EDC_VAULT_HASHICORP_HEALTH_CHECK_ENABLED=true + - EDC_VAULT_HASHICORP_TOKEN=vaultsecret0123456789 + - EDC_STATUSLIST_CALLBACK_ADDRESS=https://${DOMAIN}/statuslist + networks: + - con-x-test-network + - proxy + + provider-controlplane: + container_name: provider-controlplane + image: ghcr.io/project-construct-x/con-x-controlplane-postgresql-hashicorp-vault:latest + pull_policy: never + environment: + - JAVA_TOOL_OPTIONS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:5005 + - tx.edc.postgresql.migration.asset.enabled=false + - tx.edc.postgresql.migration.agreementbpns.enabled=false + - tx.edc.postgresql.migration.bpn.enabled=false + - tx.edc.postgresql.migration.contractdefinition.enabled=false + - tx.edc.postgresql.migration.contractnegotiation.enabled=false + - tx.edc.postgresql.migration.dataplaneinstance.enabled=false + - tx.edc.postgresql.migration.edr.enabled=false + - tx.edc.postgresql.migration.federatedcatalog.enabled=false + - tx.edc.postgresql.migration.jti-validation.enabled=false + - tx.edc.postgresql.migration.policy-monitor.enabled=false + - tx.edc.postgresql.migration.policy.enabled=false + - tx.edc.postgresql.migration.transferprocess.enabled=false + - edc.iam.trusted-issuer.example.id=did:web:${ISSUER_DOMAIN} + - edc.iam.did.web.use.https=true + - edc.iam.sts.oauth.client.secret.alias=providersecret + - edc.iam.credential.revocation.mimetype=application/json + - edc.iam.sts.oauth.token.url=http://provider-wallet:9292/api/sts/token + - edc.iam.sts.oauth.client.id=did:web:${DOMAIN} + - edc.iam.issuer.id=did:web:${DOMAIN} + - web.http.port=9000 + - web.http.path=/api + - web.http.management.port=9010 + - web.http.management.path=/management + - web.http.management.auth.key=prov-management-api-key + - web.http.management.auth.type=tokenbased + - web.http.protocol.port=9020 + - web.http.protocol.path=/dsp + - web.http.validation.port=9030 + - web.http.validation.path=/validation + - web.http.control.port=9050 + - web.http.control.path=/cpcontrol + - edc.hostname=${DOMAIN} + - edc.participant.id=did:web:${DOMAIN} + - edc.dsp.callback.address=https://${DOMAIN}/dsp + - edc.sql.schema.autocreate=true + - edc.datasource.default.url=jdbc:postgresql://shared-postgres:5432/prov_cpl + - edc.datasource.default.user=admin + - edc.datasource.default.password=password + - edc.vault.hashicorp.url=http://shared-vault:8200 + - edc.vault.hashicorp.health.check.enabled=true + - edc.vault.hashicorp.token=vaultsecret0123456789 + - tx.edc.iam.iatp.default-scopes.test.alias=org.eclipse.dspace.dcp.vc.type + - tx.edc.iam.iatp.default-scopes.test.type=MembershipCredential + - tx.edc.iam.iatp.default-scopes.test.operation=read + healthcheck: + test: [ "CMD-SHELL", "wget --spider http://localhost:9000/api/check/readiness || exit 1" ] + start_period: 10s + interval: 3s + retries: 30 + depends_on: + shared-postgres: + condition: service_healthy + vault-init: + condition: service_completed_successfully + entrypoint: [ "java", "-jar", "edc-runtime.jar", "--log-level=DEBUG" ] + ports: + - "5006:5005" # Debugger + - "39000:9000" # Default port + - "39010:9010" # Management API + - "39020:9020" # DSP API + networks: + - con-x-test-network + - proxy + + provider-dataplane: + container_name: provider-dataplane + image: ghcr.io/project-construct-x/con-x-dataplane-postgresql-hashicorp-vault:latest + pull_policy: never + environment: + - JAVA_TOOL_OPTIONS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:5005 + - web.http.public.port=9500 + - web.http.public.path=/public + - web.http.management.port=9510 + - web.http.management.path=/management + - web.http.control.port=9550 + - web.http.control.path=/dpcontrol + - edc.hostname=provider-dataplane + - edc.dpf.selector.url=https://${DOMAIN}/cpcontrol/v1/dataplanes + - edc.data.plane.self.unregistration=true + - edc.datasource.default.url=jdbc:postgresql://shared-postgres:5432/prov_dpl + - edc.datasource.default.user=admin + - edc.datasource.default.password=password + - edc.sql.schema.autocreate=true + - edc.transfer.proxy.token.signer.privatekey.alias=prov_priv + - edc.transfer.proxy.token.verifier.publickey.alias=prov_pub + - edc.vault.hashicorp.url=http://shared-vault:8200 + - edc.vault.hashicorp.health.check.enabled=true + - edc.vault.hashicorp.token=vaultsecret0123456789 + - edc.iam.trusted-issuer.example.id=did:web:${ISSUER_DOMAIN} + - edc.iam.did.web.use.https=true + - edc.iam.sts.oauth.client.secret.alias=providersecret + - edc.iam.credential.revocation.mimetype=application/json + - edc.iam.sts.oauth.token.url=http://provider-wallet:9292/api/sts/token + - edc.iam.sts.oauth.client.id=did:web:${DOMAIN} + - edc.iam.issuer.id=did:web:${DOMAIN} + - edc.dataplane.api.public.baseurl=https://${DOMAIN}/public + depends_on: + provider-controlplane: + condition: service_healthy + entrypoint: [ "java", "-jar", "edc-runtime.jar", "--log-level=DEBUG" ] + ports: + - "5007:5005" # Debugger + - "9500:9500" # Public API + networks: + - con-x-test-network + - proxy + +networks: + con-x-test-network: + name: con-x-test-network + driver: bridge + proxy: + external: true \ No newline at end of file diff --git a/docker/single-node/connector/docker-compose.yaml b/docker/single-node/connector/docker-compose.yaml new file mode 100644 index 0000000..8f7af58 --- /dev/null +++ b/docker/single-node/connector/docker-compose.yaml @@ -0,0 +1,254 @@ +# +# Copyright (c) 2026 Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V. (represented by Fraunhofer ISST) +# Copyright (c) 2026 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# 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. +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +services: + shared-postgres: + container_name: shared-postgres + image: postgres:16.4-alpine + environment: + - POSTGRES_USER=admin + - POSTGRES_PASSWORD=password + volumes: + - ./additional_config/pg_init:/docker-entrypoint-initdb.d + - pgdata:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -h 127.0.0.1 || exit 1"] + interval: 3s + timeout: 3s + retries: 20 + networks: + - con-x-test-network + + shared-vault: + container_name: shared-vault + image: vault:1.13.3 + # image: vault:1.21 + command: vault server -config=/vault/config/vault.hcl + volumes: + - ./vault/data:/vault/data + - ./vault/config:/vault/config + cap_add: + - IPC_LOCK + environment: + VAULT_ADDR: http://0.0.0.0:8200 + SKIP_SETCAP: "true" + SKIP_CHOWN: "true" + healthcheck: + test: ["CMD", "sh", "-c", "VAULT_ADDR=http://127.0.0.1:8200 vault status >/dev/null 2>&1"] + interval: 4s + timeout: 3s + retries: 20 + ports: + - "8200:8200" + networks: + - con-x-test-network + - proxy + + vault-init: + container_name: vault-init + image: alpine:3.19 + depends_on: + shared-vault: + condition: service_healthy + environment: + VAULT_ADDR: http://shared-vault:8200 + VAULT_TOKEN: ${VAULT_TOKEN} + volumes: + - ./additional_config/vault-init.sh:/scripts/init.sh:ro + + entrypoint: [ + "sh", "-c", + "apk add --no-check-certificate --no-cache curl jq openssl \ + && tr -d '\r' < /scripts/init.sh > /tmp/init.sh \ + && sh /tmp/init.sh" + ] + restart: "no" + networks: + - con-x-test-network + + provider-wallet: + container_name: provider-wallet + image: ghcr.io/project-construct-x/wallet:0.17.0-1 + pull_policy: missing + depends_on: + shared-postgres: + condition: service_healthy + vault-init: + condition: service_completed_successfully + ports: + - "1046:1045" # debugger + - "21000:80" # did API -> / + - "21100:15151" # identity API -> /api/identity + - "21500:9292" # sts API -> /api/sts + - "21600:13131" # credentials API -> /api/credentials + # - "10200:15152" # issueradmin API -> /api/issuer + # - "13132:13132" # issuance API -> /api/issuance + # - "8181:8181" # default API -> /api + # - "9999:9999" # statuslist API -> /statuslist + environment: + - JAVA_TOOL_OPTIONS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:1045 + - EDC_HOSTNAME=${DOMAIN} + - EDC_IAM_DID_WEB_USE_HTTPS=true + - EDC_ISSUER_ISSUANCE_SEND_RETRY_LIMIT=0 + - EDC_IAM_CREDENTIAL_RENEWAL_GRACEPERIOD=172800 + - EDC_IH_API_SUPERUSER_ID=admin + - EDC_IH_API_KEY_SUPERUSER=YWRtaW4.adminKey + - EDC_ISSUER_STATUSLIST_SIGNING_KEY_ALIAS=foo + - EDC_ENCRYPTION_AES_KEY_ALIAS=provider-wallet-aes-key-alias + - EDC_IAM_KEY_ALGORITHM=RSA + - EDC_IH_API_SUPERUSER_PUBLIC_KEY_ALIAS=admin3#pubkey + - EDC_IH_API_SUPERUSER_PRIVATE_KEY_ALIAS=admin3#privkey + - WEB_HTTP_DID_PORT=80 + - EDC_SQL_SCHEMA_AUTOCREATE=true + - EDC_DATASOURCE_DEFAULT_URL=jdbc:postgresql://shared-postgres:5432/prov_ih_db + - EDC_DATASOURCE_DEFAULT_USER=admin + - EDC_DATASOURCE_DEFAULT_PASSWORD=password + - EDC_VAULT_HASHICORP_URL=http://shared-vault:8200 + - EDC_VAULT_HASHICORP_HEALTH_CHECK_ENABLED=true + - EDC_VAULT_HASHICORP_TOKEN=${VAULT_TOKEN} + - EDC_STATUSLIST_CALLBACK_ADDRESS=https://${DOMAIN}/statuslist + networks: + - con-x-test-network + - proxy + + provider-controlplane: + container_name: provider-controlplane + image: ghcr.io/project-construct-x/con-x-controlplane-postgresql-hashicorp-vault:latest + pull_policy: never + environment: + - JAVA_TOOL_OPTIONS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:5005 + - tx.edc.postgresql.migration.asset.enabled=false + - tx.edc.postgresql.migration.agreementbpns.enabled=false + - tx.edc.postgresql.migration.bpn.enabled=false + - tx.edc.postgresql.migration.contractdefinition.enabled=false + - tx.edc.postgresql.migration.contractnegotiation.enabled=false + - tx.edc.postgresql.migration.dataplaneinstance.enabled=false + - tx.edc.postgresql.migration.edr.enabled=false + - tx.edc.postgresql.migration.federatedcatalog.enabled=false + - tx.edc.postgresql.migration.jti-validation.enabled=false + - tx.edc.postgresql.migration.policy-monitor.enabled=false + - tx.edc.postgresql.migration.policy.enabled=false + - tx.edc.postgresql.migration.transferprocess.enabled=false + - edc.iam.trusted-issuer.example.id=did:web:${ISSUER_DOMAIN} + - edc.iam.did.web.use.https=true + - edc.iam.sts.oauth.client.secret.alias=providersecret + - edc.iam.credential.revocation.mimetype=application/json + - edc.iam.sts.oauth.token.url=http://provider-wallet:9292/api/sts/token + - edc.iam.sts.oauth.client.id=did:web:${DOMAIN} + - edc.iam.issuer.id=did:web:${DOMAIN} + - web.http.port=9000 + - web.http.path=/api + - web.http.management.port=9010 + - web.http.management.path=/management + - web.http.management.auth.key=prov-management-api-key + - web.http.management.auth.type=tokenbased + - web.http.protocol.port=9020 + - web.http.protocol.path=/dsp + - web.http.validation.port=9030 + - web.http.validation.path=/validation + - web.http.control.port=9050 + - web.http.control.path=/cpcontrol + - edc.hostname=${DOMAIN} + - edc.participant.id=did:web:${DOMAIN} + - edc.dsp.callback.address=https://${DOMAIN}/dsp + - edc.sql.schema.autocreate=true + - edc.datasource.default.url=jdbc:postgresql://shared-postgres:5432/prov_cpl + - edc.datasource.default.user=admin + - edc.datasource.default.password=password + - edc.vault.hashicorp.url=http://shared-vault:8200 + - edc.vault.hashicorp.health.check.enabled=true + - edc.vault.hashicorp.token=${VAULT_TOKEN} + - tx.edc.iam.iatp.default-scopes.test.alias=org.eclipse.dspace.dcp.vc.type + - tx.edc.iam.iatp.default-scopes.test.type=MembershipCredential + - tx.edc.iam.iatp.default-scopes.test.operation=read + - edc.vault.hashicorp.token.scheduled-renew-enabled=false + healthcheck: + test: [ "CMD-SHELL", "wget --spider http://localhost:9000/api/check/readiness || exit 1" ] + start_period: 10s + interval: 3s + retries: 30 + depends_on: + shared-postgres: + condition: service_healthy + vault-init: + condition: service_completed_successfully + entrypoint: [ "java", "-jar", "edc-runtime.jar", "--log-level=DEBUG" ] + ports: + - "5006:5005" # Debugger + - "39000:9000" # Default port + - "39010:9010" # Management API + - "39020:9020" # DSP API + networks: + - con-x-test-network + - proxy + + provider-dataplane: + container_name: provider-dataplane + image: ghcr.io/project-construct-x/con-x-dataplane-postgresql-hashicorp-vault:latest + pull_policy: never + environment: + - JAVA_TOOL_OPTIONS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:5005 + - web.http.public.port=9500 + - web.http.public.path=/public + - web.http.management.port=9510 + - web.http.management.path=/management + - web.http.control.port=9550 + - web.http.control.path=/dpcontrol + - edc.hostname=provider-dataplane + - edc.dpf.selector.url=https://${DOMAIN}/cpcontrol/v1/dataplanes + - edc.data.plane.self.unregistration=true + - edc.datasource.default.url=jdbc:postgresql://shared-postgres:5432/prov_dpl + - edc.datasource.default.user=admin + - edc.datasource.default.password=password + - edc.sql.schema.autocreate=true + - edc.transfer.proxy.token.signer.privatekey.alias=prov_priv + - edc.transfer.proxy.token.verifier.publickey.alias=prov_pub + - edc.vault.hashicorp.url=http://shared-vault:8200 + - edc.vault.hashicorp.health.check.enabled=true + - edc.vault.hashicorp.token=${VAULT_TOKEN} + - edc.iam.trusted-issuer.example.id=did:web:${ISSUER_DOMAIN} + - edc.iam.did.web.use.https=true + - edc.iam.sts.oauth.client.secret.alias=providersecret + - edc.iam.credential.revocation.mimetype=application/json + - edc.iam.sts.oauth.token.url=http://provider-wallet:9292/api/sts/token + - edc.iam.sts.oauth.client.id=did:web:${DOMAIN} + - edc.iam.issuer.id=did:web:${DOMAIN} + - edc.dataplane.api.public.baseurl=https://${DOMAIN}/public + - edc.vault.hashicorp.token.scheduled-renew-enabled=false + depends_on: + provider-controlplane: + condition: service_healthy + entrypoint: [ "java", "-jar", "edc-runtime.jar", "--log-level=DEBUG" ] + ports: + - "5007:5005" # Debugger + - "9500:9500" # Public API + networks: + - con-x-test-network + - proxy + +networks: + con-x-test-network: + name: con-x-test-network + driver: bridge + proxy: + external: true + +volumes: + pgdata: \ No newline at end of file diff --git a/docker/single-node/connector/vault/config/vault.hcl b/docker/single-node/connector/vault/config/vault.hcl new file mode 100644 index 0000000..4cd4809 --- /dev/null +++ b/docker/single-node/connector/vault/config/vault.hcl @@ -0,0 +1,11 @@ +storage "file" { + path = "/vault/data" +} + +listener "tcp" { + address = "0.0.0.0:8200" + tls_disable = 1 +} + +ui = true + diff --git a/docker/single-node/traefik/traefik-compose.yaml b/docker/single-node/traefik/traefik-compose.yaml new file mode 100644 index 0000000..c87ee87 --- /dev/null +++ b/docker/single-node/traefik/traefik-compose.yaml @@ -0,0 +1,29 @@ +services: + traefik: + container_name: traefik + image: traefik:v3.5.0 + command: + - "--certificatesresolvers.edc-resolver.acme.email=${EMAIL:?Email must be set in the .env file}" + environment: + DOMAIN: ${DOMAIN:?${DOMAIN_MISSING_MESSAGE}} + ports: + - "80:80" + - "443:443" + # - "8080:8080" #dashboard + volumes: + - "/var/run/docker.sock:/var/run/docker.sock:ro" + - "./letsencrypt:/letsencrypt" + - "./traefik-static-conf.yaml:/etc/traefik/traefik.yaml" + - "./traefik-dynamic-conf.yaml:/etc/traefik/config/dynamic.yaml" + healthcheck: + test: ["CMD", "traefik", "healthcheck", "--ping"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 10s + networks: + - proxy + +networks: + proxy: + external: true \ No newline at end of file diff --git a/docker/single-node/traefik/traefik-dynamic-conf.yaml b/docker/single-node/traefik/traefik-dynamic-conf.yaml new file mode 100644 index 0000000..56be3c8 --- /dev/null +++ b/docker/single-node/traefik/traefik-dynamic-conf.yaml @@ -0,0 +1,210 @@ +http: + routers: + dataplane-public-api: + entrypoints: + - web + - websecure + rule: Host(`{{ env "DOMAIN" }}`) && PathPrefix(`/public`) + service: dataplane-public-api-svc + tls: + certresolver: edc-resolver + + controlplane-management-api: + entrypoints: + - web + - websecure + rule: Host(`{{ env "DOMAIN" }}`) && PathPrefix(`/management`) + service: controlplane-management-api-svc + tls: + certresolver: edc-resolver + + controlplane-dsp-api: + entrypoints: + - web + - websecure + rule: Host(`{{ env "DOMAIN" }}`) && PathPrefix(`/dsp`) + service: controlplane-dsp-api-svc + tls: + certresolver: edc-resolver + + controlplane-cpcontrol-api: + entrypoints: + - web + - websecure + rule: Host(`{{ env "DOMAIN" }}`) && PathPrefix(`/cpcontrol`) + service: controlplane-cpcontrol-api-svc + tls: + certresolver: edc-resolver + + dataplane-dpcontrol-api: + entrypoints: + - web + - websecure + rule: Host(`{{ env "DOMAIN" }}`) && PathPrefix(`/dpcontrol`) + service: dataplane-dpcontrol-api-svc + tls: + certresolver: edc-resolver + + idhub-did-api: + entrypoints: + - web + - websecure + rule: Host(`{{ env "DOMAIN" }}`) + service: idhub-did-api-svc + tls: + certresolver: edc-resolver + + idhub-wellknown-did-api: + entrypoints: + - web + - websecure + rule: Host(`{{ env "DOMAIN" }}`) && PathPrefix(`/.well-known/did.json`) + service: idhub-did-api-svc + tls: + certresolver: edc-resolver + + idhub-identity-api: + entrypoints: + - web + - websecure + rule: Host(`{{ env "DOMAIN" }}`) && PathPrefix(`/api/identity`) + service: idhub-identity-api-svc + tls: + certresolver: edc-resolver + + idhub-sts-api: + entrypoints: + - web + - websecure + rule: Host(`{{ env "DOMAIN" }}`) && PathPrefix(`/api/sts`) + service: idhub-sts-api-svc + tls: + certresolver: edc-resolver + + idhub-credentials-api: + entrypoints: + - web + - websecure + rule: Host(`{{ env "DOMAIN" }}`) && PathPrefix(`/api/credentials`) + service: idhub-credentials-api-svc + tls: + certresolver: edc-resolver + + idhub-statuslist-api: + entrypoints: + - web + - websecure + rule: Host(`{{ env "DOMAIN" }}`) && PathPrefix(`/statuslist`) + service: idhub-statuslist-api-svc + tls: + certresolver: edc-resolver + + issuance-api: + entrypoints: + - web + - websecure + rule: Host(`{{ env "DOMAIN" }}`) && PathPrefix(`/api/issuance`) + service: issuance-api-svc + tls: + certresolver: edc-resolver + + issuer-api: + entrypoints: + - web + - websecure + rule: Host(`{{ env "DOMAIN" }}`) && PathPrefix(`/api/issuer`) + service: issuer-api-svc + tls: + certresolver: edc-resolver + + # debug: + # entrypoints: + # - web + # - websecure + # rule: Host(`{{ env "DOMAIN" }}`) && PathPrefix(`/dashboard`) + # service: debug-svc + # tls: + # certresolver: edc-resolver + + vault-ui: + entrypoints: + - web + - websecure + rule: Host(`{{ env "DOMAIN" }}`) && PathPrefix(`/ui`) || PathPrefix(`/v1`) + service: vault-svc + tls: + certresolver: edc-resolver + + + + services: + dataplane-public-api-svc: + loadBalancer: + servers: + - url: http://provider-dataplane:9500 + + controlplane-management-api-svc: + loadBalancer: + servers: + - url: http://provider-controlplane:9010 + + controlplane-dsp-api-svc: + loadBalancer: + servers: + - url: http://provider-controlplane:9020 + + controlplane-cpcontrol-api-svc: + loadBalancer: + servers: + - url: http://provider-controlplane:9050 + + dataplane-dpcontrol-api-svc: + loadBalancer: + servers: + - url: http://provider-dataplane:9550 + + idhub-did-api-svc: + loadBalancer: + servers: + - url: http://provider-wallet:80 + + idhub-identity-api-svc: + loadBalancer: + servers: + - url: http://provider-wallet:15151 + + idhub-sts-api-svc: + loadBalancer: + servers: + - url: http://provider-wallet:9292 + + idhub-credentials-api-svc: + loadBalancer: + servers: + - url: http://provider-wallet:13131 + + idhub-statuslist-api-svc: + loadBalancer: + servers: + - url: http://provider-wallet:9999 + + issuance-api-svc: + loadBalancer: + servers: + - url: http://provider-wallet:13132 + + issuer-api-svc: + loadBalancer: + servers: + - url: http://provider-wallet:15152 + + + # debug-svc: + # loadBalancer: + # servers: + # - url: http://traefik:8080 + + vault-svc: + loadBalancer: + servers: + - url: http://shared-vault:8200 \ No newline at end of file diff --git a/docker/single-node/traefik/traefik-static-conf.yaml b/docker/single-node/traefik/traefik-static-conf.yaml new file mode 100644 index 0000000..3da3b48 --- /dev/null +++ b/docker/single-node/traefik/traefik-static-conf.yaml @@ -0,0 +1,35 @@ +log: + level: INFO + +providers: + docker: + watch: true + exposedByDefault: false + network: proxy + file: + directory: /etc/traefik/config # path to dynamic config + +# api: +# insecure: true #dashboard + +ping: + entryPoint: web + +entryPoints: + websecure: + address: :443 + web: + address: :80 + http: + redirections: + entryPoint: + to: websecure + scheme: https + +certificatesResolvers: + edc-resolver: + acme: + storage: /letsencrypt/acme-edc.json + httpChallenge: + entryPoint: web + # caServer: https://acme-staging-v02.api.letsencrypt.org/directory \ No newline at end of file From a3939a8ebbf5cf3a27c46f7da3acc3616780af41 Mon Sep 17 00:00:00 2001 From: Simon Malok Date: Wed, 19 Aug 2026 10:35:03 +0200 Subject: [PATCH 2/9] fix: single-node setup --- .../{local-con-x-env.bru => con-x-env.bru} | 14 +++---- .../CreateConsumerParticipant.bru | 7 ---- .../Get Consumer DID Doc.bru | 2 +- .../RequestConsumerDevMemCredential.bru | 4 -- .../CreateIssuerParticipant.bru | 7 ---- .../Prepare Issuer/Get Issuer DID Doc.bru | 2 +- .../Prepare Issuer/addConsumerHolder.bru | 5 --- .../Prepare Issuer/addProviderHolder.bru | 5 --- .../CreateProviderParticipant.bru | 7 ---- .../Get Provider DID Doc.bru | 2 +- .../RequestProviderDevMemCredential.bru | 5 --- docker/single-node/.env.example | 3 +- docker/single-node/README.md | 5 ++- .../connector/docker-compose-memory.yaml | 38 ++++++++++++++----- .../single-node/connector/docker-compose.yaml | 18 ++++----- .../traefik/traefik-dynamic-conf.yaml | 2 +- 16 files changed, 53 insertions(+), 73 deletions(-) rename bruno/single-node/environments/{local-con-x-env.bru => con-x-env.bru} (92%) diff --git a/bruno/single-node/environments/local-con-x-env.bru b/bruno/single-node/environments/con-x-env.bru similarity index 92% rename from bruno/single-node/environments/local-con-x-env.bru rename to bruno/single-node/environments/con-x-env.bru index 1d30224..cf18f21 100644 --- a/bruno/single-node/environments/local-con-x-env.bru +++ b/bruno/single-node/environments/con-x-env.bru @@ -14,7 +14,7 @@ vars { PROVIDER_STS_SECRET: XjDk9ncaJSrSfkQW PROVIDER_MANAGEMENT: {{PROVIDER_DOMAIN}}/management CONSUMER_MANAGEMENT: {{CONSUMER_DOMAIN}}/management - PROVIDER_DATAPLANE_PUBLIC: {{PROVIDER_DOMAIN}}/public + PROVIDER_DATAPLANE_PUBLIC: https://example.com/public PROVIDER_IDHUB_DID_API: {{PROVIDER_DOMAIN}} PROVIDER_IDHUB_ID_API: {{PROVIDER_DOMAIN}}/api/identity PROVIDER_IDHUB_STS_API: {{PROVIDER_DOMAIN}}/api/sts @@ -24,17 +24,17 @@ vars { PROV_ID: did:web:example.com cons_access_token: eyJraWQiOiJkaWQ6d2ViOmNvbnN1bWVyLWlkaHViOnVzZXI6Y29uc3VtZXIja2V5LTEiLCJhbGciOiJFZDI1NTE5In0.eyJhdWQiOiJkaWQ6d2ViOmNvbnN1bWVyLWlkaHViOnVzZXI6Y29uc3VtZXIiLCJzdWIiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkaHViOnVzZXI6cHJvdmlkZXIiLCJuYmYiOjE3NzAyNzg5NTQsInNjb3BlIjoib3JnLmVjbGlwc2UudHJhY3R1c3gudmMudHlwZTpNZW1iZXJzaGlwQ3JlZGVudGlhbDpyZWFkIiwiaXNzIjoiZGlkOndlYjpjb25zdW1lci1pZGh1Yjp1c2VyOmNvbnN1bWVyIiwiZXhwIjoxNzcwMjc5MjU0LCJpYXQiOjE3NzAyNzg5NTQsImp0aSI6ImFjY2Vzc3Rva2VuLTcxYThmNTA5LTgwYTktNDMwZC1iMjU0LTMxNGFiYTBkNjY5OSJ9.ipRpdi_Ekh7y4IIqhqLgHU35Fn7NNkv6e6hILXy8pZObdy33y3MKppI61424eyHwqzmh7X2kwV2S5gDy3aOKCQ prov_access_token: eyJraWQiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkaHViOnVzZXI6cHJvdmlkZXIja2V5LTEiLCJhbGciOiJFZDI1NTE5In0.eyJzdWIiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkaHViOnVzZXI6cHJvdmlkZXIiLCJhdWQiOiJkaWQ6d2ViOmNvbnN1bWVyLWlkaHViOnVzZXI6Y29uc3VtZXIiLCJuYmYiOjE3NzAyNzg5NTUsImlzcyI6ImRpZDp3ZWI6cHJvdmlkZXItaWRodWI6dXNlcjpwcm92aWRlciIsImV4cCI6MTc3MDI3OTI1NSwiaWF0IjoxNzcwMjc4OTU1LCJqdGkiOiJkNjA0MTVjOS1kMGM0LTRiNWQtYjI4My01ZmNmYjhlMDY2OGQiLCJ0b2tlbiI6ImV5SnJhV1FpT2lKa2FXUTZkMlZpT21OdmJuTjFiV1Z5TFdsa2FIVmlPblZ6WlhJNlkyOXVjM1Z0WlhJamEyVjVMVEVpTENKaGJHY2lPaUpGWkRJMU5URTVJbjAuZXlKaGRXUWlPaUprYVdRNmQyVmlPbU52Ym5OMWJXVnlMV2xrYUhWaU9uVnpaWEk2WTI5dWMzVnRaWElpTENKemRXSWlPaUprYVdRNmQyVmlPbkJ5YjNacFpHVnlMV2xrYUhWaU9uVnpaWEk2Y0hKdmRtbGtaWElpTENKdVltWWlPakUzTnpBeU56ZzVOVFFzSW5OamIzQmxJam9pYjNKbkxtVmpiR2x3YzJVdWRISmhZM1IxYzNndWRtTXVkSGx3WlRwTlpXMWlaWEp6YUdsd1EzSmxaR1Z1ZEdsaGJEcHlaV0ZrSWl3aWFYTnpJam9pWkdsa09uZGxZanBqYjI1emRXMWxjaTFwWkdoMVlqcDFjMlZ5T21OdmJuTjFiV1Z5SWl3aVpYaHdJam94Tnpjd01qYzVNalUwTENKcFlYUWlPakUzTnpBeU56ZzVOVFFzSW1wMGFTSTZJbUZqWTJWemMzUnZhMlZ1TFRjeFlUaG1OVEE1TFRnd1lUa3RORE13WkMxaU1qVTBMVE14TkdGaVlUQmtOalk1T1NKOS5pcFJwZGlfRWtoN3k0SUlxaHFMZ0hVMzVGbjdOTmt2NmU2aElMWHk4cFpPYmR5MzN5M01LcHBJNjE0MjRleUh3cXptaDdYMmt3VjJTNWdEeTNhT0tDUSJ9.42YDTnuzZ0RprqLjFw6hUoAXrgpPxyzKNFrqLdbWz6HXAiujkq32QAFU-M9gtQ0hMNcjshRZUX6DryBWxhGNDw - offerId: MQ==:YXNzZXRJZA==:MDFhN2ZjYWYtODgzOS00N2JmLTllZDAtM2Y0YjliMTFiOWM5 + offerId: MQ==:ZXBjYXQ=:YzFiODNmYzMtODc3NS00N2RmLTkzYzQtNzE2OGQ0MzMxMmNm negotiation-id: 3745ad50-6b99-4142-bf1a-509b3d0e313d - contractId: 3345f7f1-f735-4c92-8aa2-6e137203b2f9 - transferId: 3ebe55c6-900a-4c03-b213-20c5c3f0274d pullSecret: eyJraWQiOiJwcm92X3B1YiIsImFsZyI6IlJTMjU2In0.eyJpc3MiOiJhbm9ueW1vdXMiLCJhdWQiOiJkaWQ6d2ViOmNvbnN1bWVyLWlkaHViOnVzZXI6Y29uc3VtZXIiLCJzdWIiOiJhbm9ueW1vdXMiLCJpYXQiOjE3NzAyNzg5ODgsImp0aSI6IjUwYWQxMjk3LWZhN2QtNDI0ZC1hNjBhLTg5M2MwMGE4OTZhYyJ9.GkSz0qXhFmqPaLQpfPLkAvODX-iekoAQvLh3Kglhm7DApNF3PsGnv-Qzm7m8eNAqTUTWB9XXkRng_XqWmuAd-FWvzwG8d7ZaAahuykkOgX1W7vHWBMdJa-zvNm0cnzm-TQLWYCU-tDSKk_g_UrDUaFf9Jdq-avCoer3wcZrEmrf0K4o_WWs-l5hZEfDIOYHRsgoCY3P8pMcZYRjV57zdLUDl9SvLuCRR0ex0fKxJ2pb7mlaCL5ooD6fRaqWyrLvrIKZaDYfwKrX7IRJT9ePKyls9VKA9JBakh676L0jBr5-2TYG3uE9Xhyv4CZlqyck-_NyiL4Jao8-lL5FVCbPDVQ - ISS_PART_CONT: did:web:example.com - CONS_PART_CONT: did:web:example.com - PROV_PART_CONT: did:web:example.com + ISS_PART_CONT: issuer1 + CONS_PART_CONT: connector1 + PROV_PART_CONT: connector2 PROVIDER_VAULTURL: {{PROVIDER_DOMAIN}} CONSUMER_MANAGEMENT_API_KEY: prov-management-api-key ISSUER_DOMAIN: https://example.com CONSUMER_DOMAIN: https://example.com PROVIDER_DOMAIN: https://example.com + contractId: 26068646-5449-44e8-8794-fad53b7e2c0b + transferId: 56272f81-eede-429a-820a-ae750ee3230d } diff --git a/bruno/single-node/identities/Prepare Consumer ID/CreateConsumerParticipant.bru b/bruno/single-node/identities/Prepare Consumer ID/CreateConsumerParticipant.bru index 2f21fc1..f0ef5b9 100644 --- a/bruno/single-node/identities/Prepare Consumer ID/CreateConsumerParticipant.bru +++ b/bruno/single-node/identities/Prepare Consumer ID/CreateConsumerParticipant.bru @@ -43,13 +43,6 @@ body:json { } } -script:pre-request { - const cons_id = bru.getEnvVar("CONS_ID"); - //const participantContext = cons_id.split(":").slice(3).join(":").replace(/:/g, "-"); - const participantContext = cons_id - bru.setEnvVar("CONS_PART_CONT", participantContext); -} - script:post-response { const apiKey = res.getBody().apiKey.trim(); if (apiKey) { diff --git a/bruno/single-node/identities/Prepare Consumer ID/Get Consumer DID Doc.bru b/bruno/single-node/identities/Prepare Consumer ID/Get Consumer DID Doc.bru index 6cacadc..6cf08ab 100644 --- a/bruno/single-node/identities/Prepare Consumer ID/Get Consumer DID Doc.bru +++ b/bruno/single-node/identities/Prepare Consumer ID/Get Consumer DID Doc.bru @@ -5,7 +5,7 @@ meta { } get { - url: {{CONSUMER_IDHUB_DID_API}}/did.json + url: {{CONSUMER_IDHUB_DID_API}}/{{CONS_PART_CONT}} body: none auth: inherit } diff --git a/bruno/single-node/identities/Prepare Consumer ID/RequestConsumerDevMemCredential.bru b/bruno/single-node/identities/Prepare Consumer ID/RequestConsumerDevMemCredential.bru index 334cd78..eca9384 100644 --- a/bruno/single-node/identities/Prepare Consumer ID/RequestConsumerDevMemCredential.bru +++ b/bruno/single-node/identities/Prepare Consumer ID/RequestConsumerDevMemCredential.bru @@ -22,10 +22,6 @@ body:json { } script:pre-request { - const cons_id = bru.getEnvVar("CONS_ID"); - //const participantContext = cons_id.split(":").slice(3).join(":").replace(/:/g, "-"); - const participantContext = cons_id - bru.setEnvVar("CONS_PART_CONT", participantContext); req.setHeader("x-api-key", bru.getEnvVar("CONSUMER_IH_APIKEY")); } diff --git a/bruno/single-node/identities/Prepare Issuer/CreateIssuerParticipant.bru b/bruno/single-node/identities/Prepare Issuer/CreateIssuerParticipant.bru index 0e0521b..420e51f 100644 --- a/bruno/single-node/identities/Prepare Issuer/CreateIssuerParticipant.bru +++ b/bruno/single-node/identities/Prepare Issuer/CreateIssuerParticipant.bru @@ -43,13 +43,6 @@ body:json { } } -script:pre-request { - const iss_id = bru.getEnvVar("ISS_ID"); - //const participantContext = iss_id.split(":").slice(3).join(":").replace(/:/g, "-"); - const participantContext = iss_id - bru.setEnvVar("ISS_PART_CONT", participantContext); -} - script:post-response { const apiKey = res.getBody().apiKey.trim(); if (apiKey) { diff --git a/bruno/single-node/identities/Prepare Issuer/Get Issuer DID Doc.bru b/bruno/single-node/identities/Prepare Issuer/Get Issuer DID Doc.bru index 8c0d744..3ada5a9 100644 --- a/bruno/single-node/identities/Prepare Issuer/Get Issuer DID Doc.bru +++ b/bruno/single-node/identities/Prepare Issuer/Get Issuer DID Doc.bru @@ -5,7 +5,7 @@ meta { } get { - url: {{ISSUER_DID_API}}/did.json + url: {{ISSUER_DID_API}}/{{ISS_PART_CONT}} body: none auth: inherit } diff --git a/bruno/single-node/identities/Prepare Issuer/addConsumerHolder.bru b/bruno/single-node/identities/Prepare Issuer/addConsumerHolder.bru index 17e1c8f..4a70295 100644 --- a/bruno/single-node/identities/Prepare Issuer/addConsumerHolder.bru +++ b/bruno/single-node/identities/Prepare Issuer/addConsumerHolder.bru @@ -19,11 +19,6 @@ body:json { } script:pre-request { - const cons_id = bru.getEnvVar("CONS_ID"); - //const participantContext = cons_id.split(":").slice(3).join(":").replace(/:/g, "-"); - const participantContext = cons_id - bru.setEnvVar("CONS_PART_CONT", participantContext); - req.setHeader("x-api-key", bru.getEnvVar("ISSUER_APIKEY")); } diff --git a/bruno/single-node/identities/Prepare Issuer/addProviderHolder.bru b/bruno/single-node/identities/Prepare Issuer/addProviderHolder.bru index d3c48ec..a6ac224 100644 --- a/bruno/single-node/identities/Prepare Issuer/addProviderHolder.bru +++ b/bruno/single-node/identities/Prepare Issuer/addProviderHolder.bru @@ -19,11 +19,6 @@ body:json { } script:pre-request { - const prov_id = bru.getEnvVar("PROV_ID"); - //const participantContext = prov_id.split(":").slice(3).join(":").replace(/:/g, "-"); - const participantContext = prov_id - bru.setEnvVar("PROV_PART_CONT", participantContext); - req.setHeader("x-api-key", bru.getEnvVar("ISSUER_APIKEY")); } diff --git a/bruno/single-node/identities/Prepare Provider ID/CreateProviderParticipant.bru b/bruno/single-node/identities/Prepare Provider ID/CreateProviderParticipant.bru index daee4c9..592ee50 100644 --- a/bruno/single-node/identities/Prepare Provider ID/CreateProviderParticipant.bru +++ b/bruno/single-node/identities/Prepare Provider ID/CreateProviderParticipant.bru @@ -43,13 +43,6 @@ body:json { } } -script:pre-request { - const prov_id = bru.getEnvVar("PROV_ID"); - //const participantContext = prov_id.split(":").slice(3).join(":").replace(/:/g, "-"); - const participantContext = prov_id - bru.setEnvVar("PROV_PART_CONT", participantContext); -} - script:post-response { const apiKey = res.getBody().apiKey.trim(); if (apiKey) { diff --git a/bruno/single-node/identities/Prepare Provider ID/Get Provider DID Doc.bru b/bruno/single-node/identities/Prepare Provider ID/Get Provider DID Doc.bru index 1ac06f2..971ce45 100644 --- a/bruno/single-node/identities/Prepare Provider ID/Get Provider DID Doc.bru +++ b/bruno/single-node/identities/Prepare Provider ID/Get Provider DID Doc.bru @@ -5,7 +5,7 @@ meta { } get { - url: {{PROVIDER_IDHUB_DID_API}} + url: {{PROVIDER_IDHUB_DID_API}}/{{PROV_PART_CONT}} body: none auth: inherit } diff --git a/bruno/single-node/identities/Prepare Provider ID/RequestProviderDevMemCredential.bru b/bruno/single-node/identities/Prepare Provider ID/RequestProviderDevMemCredential.bru index d90a44a..bb5ba3e 100644 --- a/bruno/single-node/identities/Prepare Provider ID/RequestProviderDevMemCredential.bru +++ b/bruno/single-node/identities/Prepare Provider ID/RequestProviderDevMemCredential.bru @@ -22,11 +22,6 @@ body:json { } script:pre-request { - const prov_id = bru.getEnvVar("PROV_ID"); - // const participantContext = prov_id.split(":").slice(3).join(":").replace(/:/g, "-"); - const participantContext = prov_id - bru.setEnvVar("PROV_PART_CONT", participantContext); - req.setHeader("x-api-key", bru.getEnvVar("PROVIDER_IH_APIKEY")); } diff --git a/docker/single-node/.env.example b/docker/single-node/.env.example index fa2a3d3..9f2924c 100644 --- a/docker/single-node/.env.example +++ b/docker/single-node/.env.example @@ -1,6 +1,7 @@ EMAIL= DOMAIN= -ISSUER_DOMAIN= +DID= +ISSUER_DID= DOMAIN_MISSING_MESSAGE="Domain must be set in the .env file" diff --git a/docker/single-node/README.md b/docker/single-node/README.md index 6a96548..0ace5c4 100644 --- a/docker/single-node/README.md +++ b/docker/single-node/README.md @@ -17,12 +17,13 @@ Make sure you have... - HashiCorp Vault -The domain and a valid email must be set in the [.env-file](./.env): +The domain, did and a valid email must be set in the [.env-file](./.env): ``` EMAIL= DOMAIN= -ISSUER_DOMAIN= +DID= +ISSUER_DID= ``` diff --git a/docker/single-node/connector/docker-compose-memory.yaml b/docker/single-node/connector/docker-compose-memory.yaml index dd3e9f1..57f5c57 100644 --- a/docker/single-node/connector/docker-compose-memory.yaml +++ b/docker/single-node/connector/docker-compose-memory.yaml @@ -54,12 +54,30 @@ services: - con-x-test-network - proxy + + # Uncomment this block and comment out the HashiCorp Vault service above + # to use Vault Mock for local development and testing. + # Note: When using Vault Mock, change the `vault-init` dependency from + # `condition: service_healthy` to `condition: service_started`. + + # shared-vault: + # container_name: shared-vault + # image: ghcr.io/project-construct-x/vault-mock:sha-efcc804 + # environment: + # HASHIMOCK_TOKEN: vaultsecret0123456789 + # ports: + # - "8200:8200" + # networks: + # - con-x-test-network + # - proxy + vault-init: container_name: vault-init image: alpine:3.19 depends_on: shared-vault: - condition: service_healthy + # condition: service_healthy + condition: service_started environment: VAULT_ADDR: http://shared-vault:8200 VAULT_TOKEN: vaultsecret0123456789 @@ -137,13 +155,13 @@ services: - tx.edc.postgresql.migration.policy-monitor.enabled=false - tx.edc.postgresql.migration.policy.enabled=false - tx.edc.postgresql.migration.transferprocess.enabled=false - - edc.iam.trusted-issuer.example.id=did:web:${ISSUER_DOMAIN} + - edc.iam.trusted-issuer.example.id=${ISSUER_DID} - edc.iam.did.web.use.https=true - - edc.iam.sts.oauth.client.secret.alias=providersecret + - edc.iam.sts.oauth.client.secret.alias=consumersecret - edc.iam.credential.revocation.mimetype=application/json - edc.iam.sts.oauth.token.url=http://provider-wallet:9292/api/sts/token - - edc.iam.sts.oauth.client.id=did:web:${DOMAIN} - - edc.iam.issuer.id=did:web:${DOMAIN} + - edc.iam.sts.oauth.client.id=${DID} + - edc.iam.issuer.id=${DID} - web.http.port=9000 - web.http.path=/api - web.http.management.port=9010 @@ -157,7 +175,7 @@ services: - web.http.control.port=9050 - web.http.control.path=/cpcontrol - edc.hostname=${DOMAIN} - - edc.participant.id=did:web:${DOMAIN} + - edc.participant.id=${DID} - edc.dsp.callback.address=https://${DOMAIN}/dsp - edc.sql.schema.autocreate=true - edc.datasource.default.url=jdbc:postgresql://shared-postgres:5432/prov_cpl @@ -213,13 +231,13 @@ services: - edc.vault.hashicorp.url=http://shared-vault:8200 - edc.vault.hashicorp.health.check.enabled=true - edc.vault.hashicorp.token=vaultsecret0123456789 - - edc.iam.trusted-issuer.example.id=did:web:${ISSUER_DOMAIN} + - edc.iam.trusted-issuer.example.id=${ISSUER_DID} - edc.iam.did.web.use.https=true - - edc.iam.sts.oauth.client.secret.alias=providersecret + - edc.iam.sts.oauth.client.secret.alias=consumersecret - edc.iam.credential.revocation.mimetype=application/json - edc.iam.sts.oauth.token.url=http://provider-wallet:9292/api/sts/token - - edc.iam.sts.oauth.client.id=did:web:${DOMAIN} - - edc.iam.issuer.id=did:web:${DOMAIN} + - edc.iam.sts.oauth.client.id=${DID} + - edc.iam.issuer.id=${DID} - edc.dataplane.api.public.baseurl=https://${DOMAIN}/public depends_on: provider-controlplane: diff --git a/docker/single-node/connector/docker-compose.yaml b/docker/single-node/connector/docker-compose.yaml index 8f7af58..264bf52 100644 --- a/docker/single-node/connector/docker-compose.yaml +++ b/docker/single-node/connector/docker-compose.yaml @@ -146,13 +146,13 @@ services: - tx.edc.postgresql.migration.policy-monitor.enabled=false - tx.edc.postgresql.migration.policy.enabled=false - tx.edc.postgresql.migration.transferprocess.enabled=false - - edc.iam.trusted-issuer.example.id=did:web:${ISSUER_DOMAIN} + - edc.iam.trusted-issuer.example.id=${ISSUER_DID} - edc.iam.did.web.use.https=true - - edc.iam.sts.oauth.client.secret.alias=providersecret + - edc.iam.sts.oauth.client.secret.alias=consumersecret - edc.iam.credential.revocation.mimetype=application/json - edc.iam.sts.oauth.token.url=http://provider-wallet:9292/api/sts/token - - edc.iam.sts.oauth.client.id=did:web:${DOMAIN} - - edc.iam.issuer.id=did:web:${DOMAIN} + - edc.iam.sts.oauth.client.id=${DID} + - edc.iam.issuer.id=${DID} - web.http.port=9000 - web.http.path=/api - web.http.management.port=9010 @@ -166,7 +166,7 @@ services: - web.http.control.port=9050 - web.http.control.path=/cpcontrol - edc.hostname=${DOMAIN} - - edc.participant.id=did:web:${DOMAIN} + - edc.participant.id=${DID} - edc.dsp.callback.address=https://${DOMAIN}/dsp - edc.sql.schema.autocreate=true - edc.datasource.default.url=jdbc:postgresql://shared-postgres:5432/prov_cpl @@ -223,13 +223,13 @@ services: - edc.vault.hashicorp.url=http://shared-vault:8200 - edc.vault.hashicorp.health.check.enabled=true - edc.vault.hashicorp.token=${VAULT_TOKEN} - - edc.iam.trusted-issuer.example.id=did:web:${ISSUER_DOMAIN} + - edc.iam.trusted-issuer.example.id=${ISSUER_DID} - edc.iam.did.web.use.https=true - - edc.iam.sts.oauth.client.secret.alias=providersecret + - edc.iam.sts.oauth.client.secret.alias=consumersecret - edc.iam.credential.revocation.mimetype=application/json - edc.iam.sts.oauth.token.url=http://provider-wallet:9292/api/sts/token - - edc.iam.sts.oauth.client.id=did:web:${DOMAIN} - - edc.iam.issuer.id=did:web:${DOMAIN} + - edc.iam.sts.oauth.client.id=${DID} + - edc.iam.issuer.id=${DID} - edc.dataplane.api.public.baseurl=https://${DOMAIN}/public - edc.vault.hashicorp.token.scheduled-renew-enabled=false depends_on: diff --git a/docker/single-node/traefik/traefik-dynamic-conf.yaml b/docker/single-node/traefik/traefik-dynamic-conf.yaml index 56be3c8..2c9ee44 100644 --- a/docker/single-node/traefik/traefik-dynamic-conf.yaml +++ b/docker/single-node/traefik/traefik-dynamic-conf.yaml @@ -58,7 +58,7 @@ http: entrypoints: - web - websecure - rule: Host(`{{ env "DOMAIN" }}`) && PathPrefix(`/.well-known/did.json`) + rule: Host(`{{ env "DOMAIN" }}`) && PathRegexp(`^/.+/did\.json$`) service: idhub-did-api-svc tls: certresolver: edc-resolver From feeb430067ef1a59f20c509b0ec234543d387524 Mon Sep 17 00:00:00 2001 From: Simon Malok Date: Wed, 19 Aug 2026 10:52:53 +0200 Subject: [PATCH 3/9] Remove unused file --- .../additional_config/logging.properties | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 docker/single-node/connector/additional_config/logging.properties diff --git a/docker/single-node/connector/additional_config/logging.properties b/docker/single-node/connector/additional_config/logging.properties deleted file mode 100644 index 5c9a7fb..0000000 --- a/docker/single-node/connector/additional_config/logging.properties +++ /dev/null @@ -1,18 +0,0 @@ -handlers = java.util.logging.ConsoleHandler - -# Console Handler Config - -java.util.logging.ConsoleHandler.formatter = org.eclipse.tractusx.identityhub.monitor.ColorfulFormatter -java.util.logging.ConsoleHandler.level = FINE - -# Root level und Package-level - -.level = INFO -jakarta.json.level = OFF -jdk.event.level = OFF -okhttp3.internal.level = OFF -org.eclipse.edc.level = FINE -org.flywaydb.level = OFF -org.glassfish.level = OFF -org.jvnet.level = OFF -org.postgresql.level = OFF \ No newline at end of file From d3e5aee24d668c66ef56202636a38de87cd40048 Mon Sep 17 00:00:00 2001 From: Simon Malok Date: Wed, 19 Aug 2026 10:59:35 +0200 Subject: [PATCH 4/9] Change pull policy from never to missing --- docker/single-node/connector/docker-compose-memory.yaml | 4 ++-- docker/single-node/connector/docker-compose.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docker/single-node/connector/docker-compose-memory.yaml b/docker/single-node/connector/docker-compose-memory.yaml index 57f5c57..d7ac47e 100644 --- a/docker/single-node/connector/docker-compose-memory.yaml +++ b/docker/single-node/connector/docker-compose-memory.yaml @@ -140,7 +140,7 @@ services: provider-controlplane: container_name: provider-controlplane image: ghcr.io/project-construct-x/con-x-controlplane-postgresql-hashicorp-vault:latest - pull_policy: never + pull_policy: missing environment: - JAVA_TOOL_OPTIONS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:5005 - tx.edc.postgresql.migration.asset.enabled=false @@ -210,7 +210,7 @@ services: provider-dataplane: container_name: provider-dataplane image: ghcr.io/project-construct-x/con-x-dataplane-postgresql-hashicorp-vault:latest - pull_policy: never + pull_policy: missing environment: - JAVA_TOOL_OPTIONS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:5005 - web.http.public.port=9500 diff --git a/docker/single-node/connector/docker-compose.yaml b/docker/single-node/connector/docker-compose.yaml index 264bf52..f4d4092 100644 --- a/docker/single-node/connector/docker-compose.yaml +++ b/docker/single-node/connector/docker-compose.yaml @@ -131,7 +131,7 @@ services: provider-controlplane: container_name: provider-controlplane image: ghcr.io/project-construct-x/con-x-controlplane-postgresql-hashicorp-vault:latest - pull_policy: never + pull_policy: missing environment: - JAVA_TOOL_OPTIONS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:5005 - tx.edc.postgresql.migration.asset.enabled=false @@ -202,7 +202,7 @@ services: provider-dataplane: container_name: provider-dataplane image: ghcr.io/project-construct-x/con-x-dataplane-postgresql-hashicorp-vault:latest - pull_policy: never + pull_policy: missing environment: - JAVA_TOOL_OPTIONS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:5005 - web.http.public.port=9500 From f2cbc685de238ce730e18eb04932e8dc57cbf52b Mon Sep 17 00:00:00 2001 From: Simon Malok Date: Wed, 19 Aug 2026 11:50:03 +0200 Subject: [PATCH 5/9] Make vault-init idempotent --- .../connector/additional_config/vault-init.sh | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/docker/single-node/connector/additional_config/vault-init.sh b/docker/single-node/connector/additional_config/vault-init.sh index 368505c..43b8921 100644 --- a/docker/single-node/connector/additional_config/vault-init.sh +++ b/docker/single-node/connector/additional_config/vault-init.sh @@ -23,11 +23,25 @@ VAULT="${VAULT_ADDR:-http://shared-vault:8200}" TOKEN="${VAULT_TOKEN:?missing VAULT_TOKEN}" +secret_exists() { + local path=$1 + + curl -fsS \ + -H "X-Vault-Token: $TOKEN" \ + "$VAULT/v1/secret/data/$path" \ + >/dev/null 2>&1 +} + # function that creates and deploys a rsa keypair: create_and_store_keypair() { local prefix=$1 + if secret_exists "${prefix}_priv" && secret_exists "${prefix}_pub"; then + echo "Keypair ${prefix} already exists. Skipping." + return 0 + fi + # create rsa keypair openssl genrsa -out /tmp/${prefix}_priv_pkcs1.pem 2048 openssl pkcs8 -topk8 -nocrypt -in /tmp/${prefix}_priv_pkcs1.pem -out /tmp/${prefix}_priv.pem @@ -54,6 +68,11 @@ create_and_store_aes_key() { local prefix=$1 local aes_key + if secret_exists "${prefix}-aes-key-alias"; then + echo "AES key ${prefix} already exists. Skipping." + return 0 + fi + # AES-Key erzeugen aes_key="$(openssl rand -base64 32 | tr -d '\n')" From 5844bfe272accd0d91fb3ac0c5fa84a04ad8ae9e Mon Sep 17 00:00:00 2001 From: Simon Malok Date: Thu, 20 Aug 2026 09:25:20 +0200 Subject: [PATCH 6/9] Remove test keys from bruno collection --- bruno/single-node/environments/con-x-env.bru | 24 ++++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/bruno/single-node/environments/con-x-env.bru b/bruno/single-node/environments/con-x-env.bru index cf18f21..245c55a 100644 --- a/bruno/single-node/environments/con-x-env.bru +++ b/bruno/single-node/environments/con-x-env.bru @@ -6,12 +6,12 @@ vars { CONSUMER_IDHUB_ID_API: {{CONSUMER_DOMAIN}}/api/identity CONSUMER_IDHUB_STS_API: {{CONSUMER_DOMAIN}}/api/sts CONSUMER_IDHUB_CREDS_API: {{CONSUMER_DOMAIN}}/api/credentials - ISSUER_APIKEY: ZGlkOndlYjpsb2NhbC1pc3N1ZXItc2VydmljZTpmeC1pc3N1ZXI=.CmYgVcuzneJXqzcbj7vmld5feejy6OguIylflSrz6WTjG1HNQRvO62EafFrQjS/lVlZAwiwz2rwwZgXrbpyhcg== - CONSUMER_IH_APIKEY: ZGlkOndlYjpsb2NhbC11c2VyLWlkaHViOnVzZXI6Y29uc3VtZXI=.ObFly02OtymUNRE43uH9SblWVtsZH0NMddgm1dFYQXRekO3qXX+rHFV7NvM+DUW3lcA2PbILt5rwWYEqm7WNgw== - PROVIDER_IH_APIKEY: ZGlkOndlYjpsb2NhbC11c2VyLWlkaHViOnVzZXI6cHJvdmlkZXI=.Knip+hedL63qedBQfOvZhhrF2ooSCfP2YgjONvtmehofor2ejdw/en0MAXDBZEcXrCwYNppDMNFDsRlG5rB/Mw== + ISSUER_APIKEY: + CONSUMER_IH_APIKEY: + PROVIDER_IH_APIKEY: CONSUMER_VAULTURL: {{CONSUMER_DOMAIN}} - CONSUMER_STS_SECRET: VD0q6jOEyslSeFV2 - PROVIDER_STS_SECRET: XjDk9ncaJSrSfkQW + CONSUMER_STS_SECRET: + PROVIDER_STS_SECRET: PROVIDER_MANAGEMENT: {{PROVIDER_DOMAIN}}/management CONSUMER_MANAGEMENT: {{CONSUMER_DOMAIN}}/management PROVIDER_DATAPLANE_PUBLIC: https://example.com/public @@ -22,11 +22,11 @@ vars { ISS_ID: did:web:example.com CONS_ID: did:web:example.com PROV_ID: did:web:example.com - cons_access_token: eyJraWQiOiJkaWQ6d2ViOmNvbnN1bWVyLWlkaHViOnVzZXI6Y29uc3VtZXIja2V5LTEiLCJhbGciOiJFZDI1NTE5In0.eyJhdWQiOiJkaWQ6d2ViOmNvbnN1bWVyLWlkaHViOnVzZXI6Y29uc3VtZXIiLCJzdWIiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkaHViOnVzZXI6cHJvdmlkZXIiLCJuYmYiOjE3NzAyNzg5NTQsInNjb3BlIjoib3JnLmVjbGlwc2UudHJhY3R1c3gudmMudHlwZTpNZW1iZXJzaGlwQ3JlZGVudGlhbDpyZWFkIiwiaXNzIjoiZGlkOndlYjpjb25zdW1lci1pZGh1Yjp1c2VyOmNvbnN1bWVyIiwiZXhwIjoxNzcwMjc5MjU0LCJpYXQiOjE3NzAyNzg5NTQsImp0aSI6ImFjY2Vzc3Rva2VuLTcxYThmNTA5LTgwYTktNDMwZC1iMjU0LTMxNGFiYTBkNjY5OSJ9.ipRpdi_Ekh7y4IIqhqLgHU35Fn7NNkv6e6hILXy8pZObdy33y3MKppI61424eyHwqzmh7X2kwV2S5gDy3aOKCQ - prov_access_token: eyJraWQiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkaHViOnVzZXI6cHJvdmlkZXIja2V5LTEiLCJhbGciOiJFZDI1NTE5In0.eyJzdWIiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkaHViOnVzZXI6cHJvdmlkZXIiLCJhdWQiOiJkaWQ6d2ViOmNvbnN1bWVyLWlkaHViOnVzZXI6Y29uc3VtZXIiLCJuYmYiOjE3NzAyNzg5NTUsImlzcyI6ImRpZDp3ZWI6cHJvdmlkZXItaWRodWI6dXNlcjpwcm92aWRlciIsImV4cCI6MTc3MDI3OTI1NSwiaWF0IjoxNzcwMjc4OTU1LCJqdGkiOiJkNjA0MTVjOS1kMGM0LTRiNWQtYjI4My01ZmNmYjhlMDY2OGQiLCJ0b2tlbiI6ImV5SnJhV1FpT2lKa2FXUTZkMlZpT21OdmJuTjFiV1Z5TFdsa2FIVmlPblZ6WlhJNlkyOXVjM1Z0WlhJamEyVjVMVEVpTENKaGJHY2lPaUpGWkRJMU5URTVJbjAuZXlKaGRXUWlPaUprYVdRNmQyVmlPbU52Ym5OMWJXVnlMV2xrYUhWaU9uVnpaWEk2WTI5dWMzVnRaWElpTENKemRXSWlPaUprYVdRNmQyVmlPbkJ5YjNacFpHVnlMV2xrYUhWaU9uVnpaWEk2Y0hKdmRtbGtaWElpTENKdVltWWlPakUzTnpBeU56ZzVOVFFzSW5OamIzQmxJam9pYjNKbkxtVmpiR2x3YzJVdWRISmhZM1IxYzNndWRtTXVkSGx3WlRwTlpXMWlaWEp6YUdsd1EzSmxaR1Z1ZEdsaGJEcHlaV0ZrSWl3aWFYTnpJam9pWkdsa09uZGxZanBqYjI1emRXMWxjaTFwWkdoMVlqcDFjMlZ5T21OdmJuTjFiV1Z5SWl3aVpYaHdJam94Tnpjd01qYzVNalUwTENKcFlYUWlPakUzTnpBeU56ZzVOVFFzSW1wMGFTSTZJbUZqWTJWemMzUnZhMlZ1TFRjeFlUaG1OVEE1TFRnd1lUa3RORE13WkMxaU1qVTBMVE14TkdGaVlUQmtOalk1T1NKOS5pcFJwZGlfRWtoN3k0SUlxaHFMZ0hVMzVGbjdOTmt2NmU2aElMWHk4cFpPYmR5MzN5M01LcHBJNjE0MjRleUh3cXptaDdYMmt3VjJTNWdEeTNhT0tDUSJ9.42YDTnuzZ0RprqLjFw6hUoAXrgpPxyzKNFrqLdbWz6HXAiujkq32QAFU-M9gtQ0hMNcjshRZUX6DryBWxhGNDw - offerId: MQ==:ZXBjYXQ=:YzFiODNmYzMtODc3NS00N2RmLTkzYzQtNzE2OGQ0MzMxMmNm - negotiation-id: 3745ad50-6b99-4142-bf1a-509b3d0e313d - pullSecret: eyJraWQiOiJwcm92X3B1YiIsImFsZyI6IlJTMjU2In0.eyJpc3MiOiJhbm9ueW1vdXMiLCJhdWQiOiJkaWQ6d2ViOmNvbnN1bWVyLWlkaHViOnVzZXI6Y29uc3VtZXIiLCJzdWIiOiJhbm9ueW1vdXMiLCJpYXQiOjE3NzAyNzg5ODgsImp0aSI6IjUwYWQxMjk3LWZhN2QtNDI0ZC1hNjBhLTg5M2MwMGE4OTZhYyJ9.GkSz0qXhFmqPaLQpfPLkAvODX-iekoAQvLh3Kglhm7DApNF3PsGnv-Qzm7m8eNAqTUTWB9XXkRng_XqWmuAd-FWvzwG8d7ZaAahuykkOgX1W7vHWBMdJa-zvNm0cnzm-TQLWYCU-tDSKk_g_UrDUaFf9Jdq-avCoer3wcZrEmrf0K4o_WWs-l5hZEfDIOYHRsgoCY3P8pMcZYRjV57zdLUDl9SvLuCRR0ex0fKxJ2pb7mlaCL5ooD6fRaqWyrLvrIKZaDYfwKrX7IRJT9ePKyls9VKA9JBakh676L0jBr5-2TYG3uE9Xhyv4CZlqyck-_NyiL4Jao8-lL5FVCbPDVQ + cons_access_token: + prov_access_token: + offerId: + negotiation-id: + pullSecret: ISS_PART_CONT: issuer1 CONS_PART_CONT: connector1 PROV_PART_CONT: connector2 @@ -35,6 +35,6 @@ vars { ISSUER_DOMAIN: https://example.com CONSUMER_DOMAIN: https://example.com PROVIDER_DOMAIN: https://example.com - contractId: 26068646-5449-44e8-8794-fad53b7e2c0b - transferId: 56272f81-eede-429a-820a-ae750ee3230d + contractId: + transferId: } From bc5e9b4a5510a4fb3df1e2d7a7d1b07348e0c22a Mon Sep 17 00:00:00 2001 From: Simon Malok Date: Thu, 20 Aug 2026 11:06:16 +0200 Subject: [PATCH 7/9] Remove provider/consumer separation for single setup --- bruno/single-node/environments/con-x-env.bru | 59 +++++++---------- .../ShowConsumerCredentials.bru | 33 ---------- ...derCredentials.bru => ShowCredentials.bru} | 6 +- .../identities/Inspect Outcome/folder.bru | 2 +- .../CreateConsumerParticipant.bru | 60 ----------------- .../Get Consumer DID Doc.bru | 16 ----- .../Prepare Consumer ID/VaultSecret test.bru | 21 ------ .../identities/Prepare Consumer ID/folder.bru | 13 ---- .../CreateParticipant.bru} | 20 +++--- .../Get DID Doc.bru} | 4 +- .../RequestDevMemCredential.bru} | 6 +- .../VaultSecret test.bru | 2 +- .../VaultSecret.bru | 4 +- .../folder.bru | 4 +- .../CreateIssuerParticipant.bru | 4 +- .../{addConsumerHolder.bru => addHolder.bru} | 8 +-- .../Prepare Issuer/addProviderHolder.bru | 28 -------- .../Prepare Issuer/createDevAttestation.bru | 6 +- .../createDevMemCredentialDef.bru | 2 +- .../RequestProviderDevMemCredential.bru | 31 --------- .../Prepare Provider ID/VaultSecret.bru | 29 --------- .../Simulated DCP Flow/Consumer Token.bru | 35 ---------- .../Simulated DCP Flow/Get Credential.bru | 47 -------------- .../Simulated DCP Flow/Provider Token.bru | 30 --------- .../identities/Simulated DCP Flow/folder.bru | 34 ---------- bruno/single-node/other/Version.bru | 20 ------ .../consumer/CheckNegotiationResult.bru | 4 +- .../transactions/consumer/Get EDR.bru | 4 +- .../consumer/InitPullTransfer.bru | 8 +-- .../consumer/InitiateNegotiation.bru | 12 ++-- .../transactions/consumer/PullAssetData.bru | 2 +- .../consumer/RequestProviderCatalog.bru | 8 +-- .../transactions/provider/CreateAsset.bru | 10 ++- .../provider/CreateContractDefinition.bru | 10 ++- .../transactions/provider/CreatePolicy.bru | 2 +- docker/single-node/README.md | 8 +-- .../additional_config/pg_init/pg_init.sql | 6 +- .../connector/additional_config/vault-init.sh | 10 +-- .../connector/docker-compose-memory.yaml | 64 +++++++++---------- .../single-node/connector/docker-compose.yaml | 60 ++++++++--------- .../traefik/traefik-dynamic-conf.yaml | 26 ++++---- 41 files changed, 180 insertions(+), 578 deletions(-) delete mode 100644 bruno/single-node/identities/Inspect Outcome/ShowConsumerCredentials.bru rename bruno/single-node/identities/Inspect Outcome/{ShowProviderCredentials.bru => ShowCredentials.bru} (75%) delete mode 100644 bruno/single-node/identities/Prepare Consumer ID/CreateConsumerParticipant.bru delete mode 100644 bruno/single-node/identities/Prepare Consumer ID/Get Consumer DID Doc.bru delete mode 100644 bruno/single-node/identities/Prepare Consumer ID/VaultSecret test.bru delete mode 100644 bruno/single-node/identities/Prepare Consumer ID/folder.bru rename bruno/single-node/identities/{Prepare Provider ID/CreateProviderParticipant.bru => Prepare ID/CreateParticipant.bru} (56%) rename bruno/single-node/identities/{Prepare Provider ID/Get Provider DID Doc.bru => Prepare ID/Get DID Doc.bru} (58%) rename bruno/single-node/identities/{Prepare Consumer ID/RequestConsumerDevMemCredential.bru => Prepare ID/RequestDevMemCredential.bru} (62%) rename bruno/single-node/identities/{Prepare Provider ID => Prepare ID}/VaultSecret test.bru (79%) rename bruno/single-node/identities/{Prepare Consumer ID => Prepare ID}/VaultSecret.bru (71%) rename bruno/single-node/identities/{Prepare Provider ID => Prepare ID}/folder.bru (91%) rename bruno/single-node/identities/Prepare Issuer/{addConsumerHolder.bru => addHolder.bru} (71%) delete mode 100644 bruno/single-node/identities/Prepare Issuer/addProviderHolder.bru delete mode 100644 bruno/single-node/identities/Prepare Provider ID/RequestProviderDevMemCredential.bru delete mode 100644 bruno/single-node/identities/Prepare Provider ID/VaultSecret.bru delete mode 100644 bruno/single-node/identities/Simulated DCP Flow/Consumer Token.bru delete mode 100644 bruno/single-node/identities/Simulated DCP Flow/Get Credential.bru delete mode 100644 bruno/single-node/identities/Simulated DCP Flow/Provider Token.bru delete mode 100644 bruno/single-node/identities/Simulated DCP Flow/folder.bru delete mode 100644 bruno/single-node/other/Version.bru diff --git a/bruno/single-node/environments/con-x-env.bru b/bruno/single-node/environments/con-x-env.bru index 245c55a..bdfbad6 100644 --- a/bruno/single-node/environments/con-x-env.bru +++ b/bruno/single-node/environments/con-x-env.bru @@ -1,40 +1,27 @@ vars { - ISSUER_DID_API: {{ISSUER_DOMAIN}} - ISSUER_ID_API: {{ISSUER_DOMAIN}}/api/identity - ISSUER_ISS_API: {{ISSUER_DOMAIN}}/api/issuer - CONSUMER_IDHUB_DID_API: {{CONSUMER_DOMAIN}} - CONSUMER_IDHUB_ID_API: {{CONSUMER_DOMAIN}}/api/identity - CONSUMER_IDHUB_STS_API: {{CONSUMER_DOMAIN}}/api/sts - CONSUMER_IDHUB_CREDS_API: {{CONSUMER_DOMAIN}}/api/credentials - ISSUER_APIKEY: - CONSUMER_IH_APIKEY: - PROVIDER_IH_APIKEY: - CONSUMER_VAULTURL: {{CONSUMER_DOMAIN}} - CONSUMER_STS_SECRET: - PROVIDER_STS_SECRET: - PROVIDER_MANAGEMENT: {{PROVIDER_DOMAIN}}/management - CONSUMER_MANAGEMENT: {{CONSUMER_DOMAIN}}/management - PROVIDER_DATAPLANE_PUBLIC: https://example.com/public - PROVIDER_IDHUB_DID_API: {{PROVIDER_DOMAIN}} - PROVIDER_IDHUB_ID_API: {{PROVIDER_DOMAIN}}/api/identity - PROVIDER_IDHUB_STS_API: {{PROVIDER_DOMAIN}}/api/sts - PROVIDER_IDHUB_CREDS_API: {{PROVIDER_DOMAIN}}/api/credentials + DOMAIN: https://example.com + ID: did:web:example.com + PART_CONT: connector1 + VAULTURL: {{DOMAIN}} + MANAGEMENT: {{DOMAIN}}/management + MANAGEMENT_API_KEY: management-api-key + IDHUB_ID_API: {{DOMAIN}}/api/identity + IDHUB_DID_API: {{DOMAIN}} + IDHUB_CREDS_API: {{DOMAIN}}/api/credentials ISS_ID: did:web:example.com - CONS_ID: did:web:example.com - PROV_ID: did:web:example.com - cons_access_token: - prov_access_token: - offerId: - negotiation-id: - pullSecret: ISS_PART_CONT: issuer1 - CONS_PART_CONT: connector1 - PROV_PART_CONT: connector2 - PROVIDER_VAULTURL: {{PROVIDER_DOMAIN}} - CONSUMER_MANAGEMENT_API_KEY: prov-management-api-key - ISSUER_DOMAIN: https://example.com - CONSUMER_DOMAIN: https://example.com - PROVIDER_DOMAIN: https://example.com - contractId: - transferId: + ISSUER_DID_API: {{DOMAIN}} + ISSUER_ID_API: {{DOMAIN}}/api/identity + ISSUER_ISS_API: {{DOMAIN}}/api/issuer + COUNTERPARTY_DOMAIN: https://example.com + COUNTERPARTY_ID: did:web:example.com + COUNTERPARTY_DATAPLANE_PUBLIC: https://example.com/public + IH_APIKEY: + STS_SECRET: + ISSUER_APIKEY: + offerId: + negotiation-id: + pullSecret: + contractId: + transferId: } diff --git a/bruno/single-node/identities/Inspect Outcome/ShowConsumerCredentials.bru b/bruno/single-node/identities/Inspect Outcome/ShowConsumerCredentials.bru deleted file mode 100644 index 5886d0f..0000000 --- a/bruno/single-node/identities/Inspect Outcome/ShowConsumerCredentials.bru +++ /dev/null @@ -1,33 +0,0 @@ -meta { - name: ShowConsumerCredentials - type: http - seq: 1 -} - -get { - url: {{CONSUMER_IDHUB_ID_API}}/v1alpha/credentials - body: none - auth: none -} - -headers { - x-api-key: YWRtaW4.adminKey -} - -script:pre-request { - const t = Date.now(); - await new Promise(resolve => setTimeout(resolve, 2500)); - console.log("Waited " + (Date.now() - t) + " ms"); -} - -tests { - test("Got non-empty response", function(){ - const body = res.getBody(); - expect(body).to.be.an("array").that.is.not.empty; - }) -} - -settings { - encodeUrl: true - timeout: 0 -} diff --git a/bruno/single-node/identities/Inspect Outcome/ShowProviderCredentials.bru b/bruno/single-node/identities/Inspect Outcome/ShowCredentials.bru similarity index 75% rename from bruno/single-node/identities/Inspect Outcome/ShowProviderCredentials.bru rename to bruno/single-node/identities/Inspect Outcome/ShowCredentials.bru index 072de2c..12234ea 100644 --- a/bruno/single-node/identities/Inspect Outcome/ShowProviderCredentials.bru +++ b/bruno/single-node/identities/Inspect Outcome/ShowCredentials.bru @@ -1,11 +1,11 @@ meta { - name: ShowProviderCredentials + name: ShowCredentials type: http - seq: 2 + seq: 1 } get { - url: {{PROVIDER_IDHUB_ID_API}}/v1alpha/credentials + url: {{IDHUB_ID_API}}/v1alpha/credentials body: none auth: none } diff --git a/bruno/single-node/identities/Inspect Outcome/folder.bru b/bruno/single-node/identities/Inspect Outcome/folder.bru index d3d8460..cc4c816 100644 --- a/bruno/single-node/identities/Inspect Outcome/folder.bru +++ b/bruno/single-node/identities/Inspect Outcome/folder.bru @@ -1,6 +1,6 @@ meta { name: Inspect Outcome - seq: 4 + seq: 3 } auth { diff --git a/bruno/single-node/identities/Prepare Consumer ID/CreateConsumerParticipant.bru b/bruno/single-node/identities/Prepare Consumer ID/CreateConsumerParticipant.bru deleted file mode 100644 index f0ef5b9..0000000 --- a/bruno/single-node/identities/Prepare Consumer ID/CreateConsumerParticipant.bru +++ /dev/null @@ -1,60 +0,0 @@ -meta { - name: CreateConsumerParticipant - type: http - seq: 1 -} - -post { - url: {{CONSUMER_IDHUB_ID_API}}/v1alpha/participants - body: json - auth: inherit -} - -headers { - x-api-key: YWRtaW4.adminKey -} - -body:json { - { - "roles": [], - "serviceEndpoints": [ - { - "id": "ConsumerCredentialService-ID", - "type": "CredentialService", - "serviceEndpoint": "{{CONSUMER_DOMAIN}}/api/credentials/v1/participants/{{CONS_PART_CONT}}" - }, - { - "id": "ConsumerIssuerService-ID", - "type": "IssuerService", - "serviceEndpoint": "{{CONSUMER_DOMAIN}}/api/issuance/v1alpha/participants/{{CONS_PART_CONT}}" - } - ], - "active": true, - "participantContextId": "{{CONS_PART_CONT}}", - "did": "{{CONS_ID}}", - "key": { - "keyId": "{{CONS_ID}}#key-1", - "privateKeyAlias": "{{CONS_ID}}-alias", - "keyGeneratorParams": { - "algorithm": "EdDSA", - "curve": "Ed25519" - } - } - } -} - -script:post-response { - const apiKey = res.getBody().apiKey.trim(); - if (apiKey) { - bru.setEnvVar("CONSUMER_IH_APIKEY", apiKey); - } - const stsSecret = res.getBody().clientSecret.trim(); - if (stsSecret) { - bru.setEnvVar("CONSUMER_STS_SECRET", stsSecret) - } -} - -settings { - encodeUrl: true - timeout: 0 -} diff --git a/bruno/single-node/identities/Prepare Consumer ID/Get Consumer DID Doc.bru b/bruno/single-node/identities/Prepare Consumer ID/Get Consumer DID Doc.bru deleted file mode 100644 index 6cf08ab..0000000 --- a/bruno/single-node/identities/Prepare Consumer ID/Get Consumer DID Doc.bru +++ /dev/null @@ -1,16 +0,0 @@ -meta { - name: Get Consumer DID Doc - type: http - seq: 3 -} - -get { - url: {{CONSUMER_IDHUB_DID_API}}/{{CONS_PART_CONT}} - body: none - auth: inherit -} - -settings { - encodeUrl: true - timeout: 0 -} diff --git a/bruno/single-node/identities/Prepare Consumer ID/VaultSecret test.bru b/bruno/single-node/identities/Prepare Consumer ID/VaultSecret test.bru deleted file mode 100644 index fa631b8..0000000 --- a/bruno/single-node/identities/Prepare Consumer ID/VaultSecret test.bru +++ /dev/null @@ -1,21 +0,0 @@ -meta { - name: VaultSecret test - type: http - seq: 5 -} - -get { - url: {{CONSUMER_VAULTURL}}/v1/secret/data/consumersecret - body: none - auth: inherit -} - -headers { - X-Vault-Token: vaultsecret0123456789 - ~X-Vault-Token: -} - -settings { - encodeUrl: true - timeout: 0 -} diff --git a/bruno/single-node/identities/Prepare Consumer ID/folder.bru b/bruno/single-node/identities/Prepare Consumer ID/folder.bru deleted file mode 100644 index e92dbb3..0000000 --- a/bruno/single-node/identities/Prepare Consumer ID/folder.bru +++ /dev/null @@ -1,13 +0,0 @@ -meta { - name: Prepare Consumer ID - seq: 2 -} - -auth { - mode: inherit -} - -docs { - The requests in this folder are necessary for creating the identity of the consumer participant. - We are doing an initial registration at the identity hub. Then we take a look at the created DID document. Then we trigger a credential request toward the trusted issuer. And also, we are storing the STS secret that the identity hub gave us, at the vault. -} diff --git a/bruno/single-node/identities/Prepare Provider ID/CreateProviderParticipant.bru b/bruno/single-node/identities/Prepare ID/CreateParticipant.bru similarity index 56% rename from bruno/single-node/identities/Prepare Provider ID/CreateProviderParticipant.bru rename to bruno/single-node/identities/Prepare ID/CreateParticipant.bru index 592ee50..38b2303 100644 --- a/bruno/single-node/identities/Prepare Provider ID/CreateProviderParticipant.bru +++ b/bruno/single-node/identities/Prepare ID/CreateParticipant.bru @@ -1,11 +1,11 @@ meta { - name: CreateProviderParticipant + name: CreateParticipant type: http seq: 1 } post { - url: {{PROVIDER_IDHUB_ID_API}}/v1alpha/participants + url: {{IDHUB_ID_API}}/v1alpha/participants body: json auth: inherit } @@ -21,20 +21,20 @@ body:json { { "id": "ProviderCredentialService-ID", "type": "CredentialService", - "serviceEndpoint": "{{PROVIDER_DOMAIN}}/api/credentials/v1/participants/{{PROV_PART_CONT}}" + "serviceEndpoint": "{{DOMAIN}}/api/credentials/v1/participants/{{PART_CONT}}" }, { "id": "ProviderIssuerService-ID", "type": "IssuerService", - "serviceEndpoint": "{{PROVIDER_DOMAIN}}/api/issuance/v1alpha/participants/{{PROV_PART_CONT}}" + "serviceEndpoint": "{{DOMAIN}}/api/issuance/v1alpha/participants/{{PART_CONT}}" } ], "active": true, - "participantContextId": "{{PROV_PART_CONT}}", - "did": "{{PROV_ID}}", + "participantContextId": "{{PART_CONT}}", + "did": "{{ID}}", "key": { - "keyId": "{{PROV_ID}}#key-1", - "privateKeyAlias": "{{PROV_ID}}-alias", + "keyId": "{{ID}}#key-1", + "privateKeyAlias": "{{ID}}-alias", "keyGeneratorParams": { "algorithm": "EdDSA", "curve": "Ed25519" @@ -46,11 +46,11 @@ body:json { script:post-response { const apiKey = res.getBody().apiKey.trim(); if (apiKey) { - bru.setEnvVar("PROVIDER_IH_APIKEY", apiKey); + bru.setEnvVar("IH_APIKEY", apiKey); } const stsSecret = res.getBody().clientSecret.trim(); if (stsSecret) { - bru.setEnvVar("PROVIDER_STS_SECRET", stsSecret) + bru.setEnvVar("STS_SECRET", stsSecret) } } diff --git a/bruno/single-node/identities/Prepare Provider ID/Get Provider DID Doc.bru b/bruno/single-node/identities/Prepare ID/Get DID Doc.bru similarity index 58% rename from bruno/single-node/identities/Prepare Provider ID/Get Provider DID Doc.bru rename to bruno/single-node/identities/Prepare ID/Get DID Doc.bru index 971ce45..23fb31a 100644 --- a/bruno/single-node/identities/Prepare Provider ID/Get Provider DID Doc.bru +++ b/bruno/single-node/identities/Prepare ID/Get DID Doc.bru @@ -1,11 +1,11 @@ meta { - name: Get Provider DID Doc + name: Get DID Doc type: http seq: 3 } get { - url: {{PROVIDER_IDHUB_DID_API}}/{{PROV_PART_CONT}} + url: {{IDHUB_DID_API}}/{{PART_CONT}} body: none auth: inherit } diff --git a/bruno/single-node/identities/Prepare Consumer ID/RequestConsumerDevMemCredential.bru b/bruno/single-node/identities/Prepare ID/RequestDevMemCredential.bru similarity index 62% rename from bruno/single-node/identities/Prepare Consumer ID/RequestConsumerDevMemCredential.bru rename to bruno/single-node/identities/Prepare ID/RequestDevMemCredential.bru index eca9384..e5600d3 100644 --- a/bruno/single-node/identities/Prepare Consumer ID/RequestConsumerDevMemCredential.bru +++ b/bruno/single-node/identities/Prepare ID/RequestDevMemCredential.bru @@ -1,11 +1,11 @@ meta { - name: RequestConsumerDevMemCredential + name: RequestDevMemCredential type: http seq: 2 } post { - url: {{CONSUMER_IDHUB_ID_API}}/v1alpha/participants/{{CONS_PART_CONT}}/credentials/request + url: {{IDHUB_ID_API}}/v1alpha/participants/{{PART_CONT}}/credentials/request body: json auth: none } @@ -22,7 +22,7 @@ body:json { } script:pre-request { - req.setHeader("x-api-key", bru.getEnvVar("CONSUMER_IH_APIKEY")); + req.setHeader("x-api-key", bru.getEnvVar("IH_APIKEY")); } settings { diff --git a/bruno/single-node/identities/Prepare Provider ID/VaultSecret test.bru b/bruno/single-node/identities/Prepare ID/VaultSecret test.bru similarity index 79% rename from bruno/single-node/identities/Prepare Provider ID/VaultSecret test.bru rename to bruno/single-node/identities/Prepare ID/VaultSecret test.bru index 8cf7cbd..764dd70 100644 --- a/bruno/single-node/identities/Prepare Provider ID/VaultSecret test.bru +++ b/bruno/single-node/identities/Prepare ID/VaultSecret test.bru @@ -5,7 +5,7 @@ meta { } get { - url: {{PROVIDER_VAULTURL}}/v1/secret/data/providersecret + url: {{VAULTURL}}/v1/secret/data/vaultsecret body: none auth: inherit } diff --git a/bruno/single-node/identities/Prepare Consumer ID/VaultSecret.bru b/bruno/single-node/identities/Prepare ID/VaultSecret.bru similarity index 71% rename from bruno/single-node/identities/Prepare Consumer ID/VaultSecret.bru rename to bruno/single-node/identities/Prepare ID/VaultSecret.bru index b3c7266..25feee5 100644 --- a/bruno/single-node/identities/Prepare Consumer ID/VaultSecret.bru +++ b/bruno/single-node/identities/Prepare ID/VaultSecret.bru @@ -5,7 +5,7 @@ meta { } post { - url: {{CONSUMER_VAULTURL}}/v1/secret/data/consumersecret + url: {{VAULTURL}}/v1/secret/data/vaultsecret body: json auth: inherit } @@ -18,7 +18,7 @@ headers { body:json { { "data": { - "content": "{{CONSUMER_STS_SECRET}}" + "content": "{{STS_SECRET}}" } } } diff --git a/bruno/single-node/identities/Prepare Provider ID/folder.bru b/bruno/single-node/identities/Prepare ID/folder.bru similarity index 91% rename from bruno/single-node/identities/Prepare Provider ID/folder.bru rename to bruno/single-node/identities/Prepare ID/folder.bru index 59be317..701654e 100644 --- a/bruno/single-node/identities/Prepare Provider ID/folder.bru +++ b/bruno/single-node/identities/Prepare ID/folder.bru @@ -1,6 +1,6 @@ meta { - name: Prepare Provider ID - seq: 3 + name: Prepare ID + seq: 2 } auth { diff --git a/bruno/single-node/identities/Prepare Issuer/CreateIssuerParticipant.bru b/bruno/single-node/identities/Prepare Issuer/CreateIssuerParticipant.bru index 420e51f..2a1dfb5 100644 --- a/bruno/single-node/identities/Prepare Issuer/CreateIssuerParticipant.bru +++ b/bruno/single-node/identities/Prepare Issuer/CreateIssuerParticipant.bru @@ -21,12 +21,12 @@ body:json { { "id": "IssuerIssuerService-ID", "type": "IssuerService", - "serviceEndpoint": "{{ISSUER_DOMAIN}}/api/issuance/v1alpha/participants/{{ISS_PART_CONT}}" + "serviceEndpoint": "{{DOMAIN}}/api/issuance/v1alpha/participants/{{ISS_PART_CONT}}" }, { "id": "IssuerCredentialService-ID", "type": "CredentialService", - "serviceEndpoint": "{{ISSUER_DOMAIN}}/api/credentials/v1/participants/{{ISS_PART_CONT}}" + "serviceEndpoint": "{{DOMAIN}}/api/credentials/v1/participants/{{ISS_PART_CONT}}" } ], "active": true, diff --git a/bruno/single-node/identities/Prepare Issuer/addConsumerHolder.bru b/bruno/single-node/identities/Prepare Issuer/addHolder.bru similarity index 71% rename from bruno/single-node/identities/Prepare Issuer/addConsumerHolder.bru rename to bruno/single-node/identities/Prepare Issuer/addHolder.bru index 4a70295..3060b88 100644 --- a/bruno/single-node/identities/Prepare Issuer/addConsumerHolder.bru +++ b/bruno/single-node/identities/Prepare Issuer/addHolder.bru @@ -1,5 +1,5 @@ meta { - name: addConsumerHolder + name: addHolder type: http seq: 3 } @@ -12,9 +12,9 @@ post { body:json { { - "holderId" : "{{CONS_ID}}", - "did" : "{{CONS_ID}}", - "name" : "{{CONS_PART_CONT}}" + "holderId" : "DID", + "did" : "DID", + "name" : "PART_CONT" } } diff --git a/bruno/single-node/identities/Prepare Issuer/addProviderHolder.bru b/bruno/single-node/identities/Prepare Issuer/addProviderHolder.bru deleted file mode 100644 index a6ac224..0000000 --- a/bruno/single-node/identities/Prepare Issuer/addProviderHolder.bru +++ /dev/null @@ -1,28 +0,0 @@ -meta { - name: addProviderHolder - type: http - seq: 4 -} - -post { - url: {{ISSUER_ISS_API}}/v1alpha/participants/{{ISS_PART_CONT}}/holders - body: json - auth: inherit -} - -body:json { - { - "holderId" : "{{PROV_ID}}", - "did" : "{{PROV_ID}}", - "name" : "{{PROV_PART_CONT}}" - } -} - -script:pre-request { - req.setHeader("x-api-key", bru.getEnvVar("ISSUER_APIKEY")); -} - -settings { - encodeUrl: true - timeout: 0 -} diff --git a/bruno/single-node/identities/Prepare Issuer/createDevAttestation.bru b/bruno/single-node/identities/Prepare Issuer/createDevAttestation.bru index 1e9801e..a2576a8 100644 --- a/bruno/single-node/identities/Prepare Issuer/createDevAttestation.bru +++ b/bruno/single-node/identities/Prepare Issuer/createDevAttestation.bru @@ -1,7 +1,7 @@ meta { name: createDevAttestation type: http - seq: 5 + seq: 4 } post { @@ -19,14 +19,14 @@ body:json { "attestationType": "dev", "id": "dev-def-1", "configuration": { - "{{CONS_ID}}": { + "did:web:example.com": { "isConsumer": true, "isProvider": false, "foo": { "bar": 123 } }, - "{{PROV_ID}}": { + "did:web:example2.com": { "isConsumer": false, "isProvider": true, "foo": { diff --git a/bruno/single-node/identities/Prepare Issuer/createDevMemCredentialDef.bru b/bruno/single-node/identities/Prepare Issuer/createDevMemCredentialDef.bru index fe36fe1..8802f44 100644 --- a/bruno/single-node/identities/Prepare Issuer/createDevMemCredentialDef.bru +++ b/bruno/single-node/identities/Prepare Issuer/createDevMemCredentialDef.bru @@ -1,7 +1,7 @@ meta { name: createDevMemCredentialDef type: http - seq: 6 + seq: 5 } post { diff --git a/bruno/single-node/identities/Prepare Provider ID/RequestProviderDevMemCredential.bru b/bruno/single-node/identities/Prepare Provider ID/RequestProviderDevMemCredential.bru deleted file mode 100644 index bb5ba3e..0000000 --- a/bruno/single-node/identities/Prepare Provider ID/RequestProviderDevMemCredential.bru +++ /dev/null @@ -1,31 +0,0 @@ -meta { - name: RequestProviderDevMemCredential - type: http - seq: 2 -} - -post { - url: {{PROVIDER_IDHUB_ID_API}}/v1alpha/participants/{{PROV_PART_CONT}}/credentials/request - body: json - auth: none -} - -body:json { - { - "issuerDid": "{{ISS_ID}}", - "credentials": [{ - "format": "VC1_0_JWT", - "type": "MembershipCredential", - "id": "dev-credential-def-1" - }] - } -} - -script:pre-request { - req.setHeader("x-api-key", bru.getEnvVar("PROVIDER_IH_APIKEY")); -} - -settings { - encodeUrl: true - timeout: 0 -} diff --git a/bruno/single-node/identities/Prepare Provider ID/VaultSecret.bru b/bruno/single-node/identities/Prepare Provider ID/VaultSecret.bru deleted file mode 100644 index 806c7c0..0000000 --- a/bruno/single-node/identities/Prepare Provider ID/VaultSecret.bru +++ /dev/null @@ -1,29 +0,0 @@ -meta { - name: VaultSecret - type: http - seq: 4 -} - -post { - url: {{PROVIDER_VAULTURL}}/v1/secret/data/providersecret - body: json - auth: inherit -} - -headers { - X-Vault-Token: vaultsecret0123456789 - ~X-Vault-Token: -} - -body:json { - { - "data": { - "content": "{{PROVIDER_STS_SECRET}}" - } - } -} - -settings { - encodeUrl: true - timeout: 0 -} diff --git a/bruno/single-node/identities/Simulated DCP Flow/Consumer Token.bru b/bruno/single-node/identities/Simulated DCP Flow/Consumer Token.bru deleted file mode 100644 index 16b2325..0000000 --- a/bruno/single-node/identities/Simulated DCP Flow/Consumer Token.bru +++ /dev/null @@ -1,35 +0,0 @@ -meta { - name: Consumer Token - type: http - seq: 1 -} - -post { - url: {{CONSUMER_IDHUB_STS_API}}/token - body: formUrlEncoded - auth: inherit -} - -body:form-urlencoded { - grant_type: client_credentials - client_secret: {{CONSUMER_STS_SECRET}} - client_id: {{CONS_ID}} - audience: {{PROV_ID}} - bearer_access_scope: org.eclipse.dspace.dcp.vc.type:MembershipCredential:read -} - -script:post-response { - const atob = require("atob"); - const accessToken = res.getBody().access_token.trim(); - const parts = accessToken.split("."); - const payload = atob(parts[1]); - const payloadObject = JSON.parse(payload); - const internalToken = payloadObject.token.trim(); - - bru.setEnvVar("cons_access_token", internalToken); -} - -settings { - encodeUrl: true - timeout: 0 -} diff --git a/bruno/single-node/identities/Simulated DCP Flow/Get Credential.bru b/bruno/single-node/identities/Simulated DCP Flow/Get Credential.bru deleted file mode 100644 index 8ea42d7..0000000 --- a/bruno/single-node/identities/Simulated DCP Flow/Get Credential.bru +++ /dev/null @@ -1,47 +0,0 @@ -meta { - name: Get Credential - type: http - seq: 3 -} - -post { - url: {{CONSUMER_IDHUB_CREDS_API}}/v1/participants/{{CONS_PART_CONT}}/presentations/query - body: json - auth: bearer -} - -auth:bearer { - token: {{prov_access_token}} -} - -body:json { - { - "@context": [ - "https://w3id.org/dspace-dcp/v1.0/dcp.jsonld", - "https://identity.foundation/presentation-exchange/submission/v1" - ], - "type": "PresentationQueryMessage", - "presentationDefinition": null, - "scope": [ - "org.eclipse.dspace.dcp.vc.type:MembershipCredential:read" - ] - } -} - -tests { - test("Contains VerifiableCredential", function(){ - const atob = require("atob"); - const presentation = res.getBody().presentation[0]; - const decodedPayload = JSON.parse(atob(presentation.split(".")[1])); - - const verifiableCred = atob(decodedPayload.vp.verifiableCredential[0].split(".")[1]); - - const success = verifiableCred.includes("VerifiableCredential") - expect(success); - }) -} - -settings { - encodeUrl: true - timeout: 0 -} diff --git a/bruno/single-node/identities/Simulated DCP Flow/Provider Token.bru b/bruno/single-node/identities/Simulated DCP Flow/Provider Token.bru deleted file mode 100644 index 3ec92f6..0000000 --- a/bruno/single-node/identities/Simulated DCP Flow/Provider Token.bru +++ /dev/null @@ -1,30 +0,0 @@ -meta { - name: Provider Token - type: http - seq: 2 -} - -post { - url: {{PROVIDER_IDHUB_STS_API}}/token - body: formUrlEncoded - auth: inherit -} - -body:form-urlencoded { - grant_type: client_credentials - client_secret: {{PROVIDER_STS_SECRET}} - client_id: {{PROV_ID}} - audience: {{CONS_ID}} - token: {{cons_access_token}} -} - -script:post-response { - const accessToken = res.getBody().access_token.trim(); - - bru.setEnvVar("prov_access_token", accessToken); -} - -settings { - encodeUrl: true - timeout: 0 -} diff --git a/bruno/single-node/identities/Simulated DCP Flow/folder.bru b/bruno/single-node/identities/Simulated DCP Flow/folder.bru deleted file mode 100644 index 5e25d16..0000000 --- a/bruno/single-node/identities/Simulated DCP Flow/folder.bru +++ /dev/null @@ -1,34 +0,0 @@ -meta { - name: Simulated DCP Flow - seq: 5 -} - -auth { - mode: inherit -} - -docs { - This section is meant to show in principle, what happens during a DCP protocol validated interaction between two controlplanes. It also serves as a final test. If these requests do succeed, then we can be sure that all previous steps went well. - - Let's assume that the consumer intends to obtain the DSP catolog from the provider. - Then the consumer will request a self signed SI token from his own Identity-Hub's secure token service (STS), see the "Consumer Token" request. - - In that request body, the consumer informs the STS about the intended audience and the credential type he wants to show to the other side. - - In the request body, we should receive an access token in JWT format, the "consumer-access-token". - - Please feel free to decode the "consumer-access-token" with a tool of your choice and observe that token's payload. You will find, that this payload itself contains another JWT inside the "token" claim. - - The entire "consumer-access-token" will now be sent by the consumer-side-EDC to the provider-side-EDC via the "Authentication" header of a request to the according DSP-catolog request api endpoint. Since the "consumer-access-token" is signed with the consumer private key, the provider can now download the consumer's DID document, read the consumer's public key and use it to check that the JWT's signature is valid. - - We are not doing the signature check here in this small simulation, so let's just assume that it turned out positive. - - Now the provider wants to see, which credentials the consumer is going to show him. For that, he needs to retrieve it from the consumer's credential service. The URL can be found in the consumer's DID document. - - But first, he needs to talk to his own secure token service (STS). So he is unwrapping the "token" claim and sending it to his own STS, see the "Post Request Script" of the "Consumer Token" request and the request body in the "Provider Token" request. - - The response of the provider's STS will contain another access token, we are calling it "provider access token". This "provider access token" can now be attached as an "authorization" header to the provider's request to the consumer's credential service. - - The response of the consumer credential service contains the verifiable presentation, which itself now contains the verfiable credential, which the trusted issuer initially handed out to the consumer. - -} diff --git a/bruno/single-node/other/Version.bru b/bruno/single-node/other/Version.bru deleted file mode 100644 index d219789..0000000 --- a/bruno/single-node/other/Version.bru +++ /dev/null @@ -1,20 +0,0 @@ -meta { - name: Version - type: http - seq: 7 -} - -get { - url: http://localhost:29020/dsp/.well-known/dspace-version - body: none - auth: inherit -} - -headers { - Accept: application/json -} - -settings { - encodeUrl: true - timeout: 0 -} diff --git a/bruno/single-node/transactions/consumer/CheckNegotiationResult.bru b/bruno/single-node/transactions/consumer/CheckNegotiationResult.bru index 17551cb..70a3ac2 100644 --- a/bruno/single-node/transactions/consumer/CheckNegotiationResult.bru +++ b/bruno/single-node/transactions/consumer/CheckNegotiationResult.bru @@ -5,7 +5,7 @@ meta { } get { - url: {{CONSUMER_MANAGEMENT}}/v3/contractnegotiations/{{negotiation-id}} + url: {{MANAGEMENT}}/v3/contractnegotiations/{{negotiation-id}} body: none auth: apikey } @@ -16,7 +16,7 @@ headers { auth:apikey { key: X-Api-key - value: {{CONSUMER_MANAGEMENT_API_KEY}} + value: {{MANAGEMENT_API_KEY}} placement: header } diff --git a/bruno/single-node/transactions/consumer/Get EDR.bru b/bruno/single-node/transactions/consumer/Get EDR.bru index 8c282a2..70484d5 100644 --- a/bruno/single-node/transactions/consumer/Get EDR.bru +++ b/bruno/single-node/transactions/consumer/Get EDR.bru @@ -5,7 +5,7 @@ meta { } get { - url: {{CONSUMER_MANAGEMENT}}/v3/edrs/{{transferId}}/dataaddress + url: {{MANAGEMENT}}/v3/edrs/{{transferId}}/dataaddress body: none auth: apikey } @@ -16,7 +16,7 @@ headers { auth:apikey { key: X-Api-key - value: {{CONSUMER_MANAGEMENT_API_KEY}} + value: {{MANAGEMENT_API_KEY}} placement: header } diff --git a/bruno/single-node/transactions/consumer/InitPullTransfer.bru b/bruno/single-node/transactions/consumer/InitPullTransfer.bru index 72e0a18..d25cbdc 100644 --- a/bruno/single-node/transactions/consumer/InitPullTransfer.bru +++ b/bruno/single-node/transactions/consumer/InitPullTransfer.bru @@ -5,14 +5,14 @@ meta { } post { - url: {{CONSUMER_MANAGEMENT}}/v3/transferprocesses + url: {{MANAGEMENT}}/v3/transferprocesses body: json auth: apikey } auth:apikey { key: X-Api-key - value: {{CONSUMER_MANAGEMENT_API_KEY}} + value: {{MANAGEMENT_API_KEY}} placement: header } @@ -24,8 +24,8 @@ body:json { "@type": "TransferRequestDto", "protocol": "dataspace-protocol-http:2025-1", "contractId": "{{contractId}}", - "counterPartyAddress": "{{PROVIDER_DOMAIN}}/dsp/2025-1", - "connectorId": "{{PROV_ID}}", + "counterPartyAddress": "{{COUNTERPARTY_DOMAIN}}/dsp/2025-1", + "connectorId": "{{COUNTERPARTY_ID}}", "transferType": "HttpData-PULL" } } diff --git a/bruno/single-node/transactions/consumer/InitiateNegotiation.bru b/bruno/single-node/transactions/consumer/InitiateNegotiation.bru index b9c112f..d3c8e28 100644 --- a/bruno/single-node/transactions/consumer/InitiateNegotiation.bru +++ b/bruno/single-node/transactions/consumer/InitiateNegotiation.bru @@ -5,7 +5,7 @@ meta { } post { - url: {{CONSUMER_MANAGEMENT}}/v3/contractnegotiations + url: {{MANAGEMENT}}/v3/contractnegotiations body: json auth: apikey } @@ -16,7 +16,7 @@ headers { auth:apikey { key: X-Api-key - value: {{CONSUMER_MANAGEMENT_API_KEY}} + value: {{MANAGEMENT_API_KEY}} placement: header } @@ -27,15 +27,15 @@ body:json { "odrl": "http://www.w3.org/ns/odrl/2/" }, "@type": "ContractRequest", - "counterPartyAddress": "{{PROVIDER_DOMAIN}}/dsp/2025-1", - "connectorId": "{{PROV_ID}}", + "counterPartyAddress": "{{COUNTERPARTY_DOMAIN}}/dsp/2025-1", + "connectorId": "{{COUNTERPARTY_ID}}", "protocol": "dataspace-protocol-http:2025-1", "policy": { "@context": "http://www.w3.org/ns/odrl.jsonld", "@id": "{{offerId}}", "@type": "Offer", - "assigner": "{{PROV_ID}}", - "assignee": "{{CONS_ID}}", + "assigner": "{{COUNTERPARTY_ID}}", + "assignee": "{{ID}}", "target": "assetId" } } diff --git a/bruno/single-node/transactions/consumer/PullAssetData.bru b/bruno/single-node/transactions/consumer/PullAssetData.bru index df33451..6199c0a 100644 --- a/bruno/single-node/transactions/consumer/PullAssetData.bru +++ b/bruno/single-node/transactions/consumer/PullAssetData.bru @@ -5,7 +5,7 @@ meta { } get { - url: {{PROVIDER_DATAPLANE_PUBLIC}} + url: {{COUNTERPARTY_DATAPLANE_PUBLIC}} body: none auth: inherit } diff --git a/bruno/single-node/transactions/consumer/RequestProviderCatalog.bru b/bruno/single-node/transactions/consumer/RequestProviderCatalog.bru index a603158..a6c79c4 100644 --- a/bruno/single-node/transactions/consumer/RequestProviderCatalog.bru +++ b/bruno/single-node/transactions/consumer/RequestProviderCatalog.bru @@ -5,14 +5,14 @@ meta { } post { - url: {{CONSUMER_MANAGEMENT}}/v3/catalog/request + url: {{MANAGEMENT}}/v3/catalog/request body: json auth: apikey } auth:apikey { key: X-Api-key - value: {{CONSUMER_MANAGEMENT_API_KEY}} + value: {{MANAGEMENT_API_KEY}} placement: header } @@ -21,8 +21,8 @@ body:json { "@context": { "@vocab": "https://w3id.org/edc/v0.0.1/ns/" }, - "counterPartyAddress": "{{PROVIDER_DOMAIN}}/dsp/2025-1", - "counterPartyId": "{{PROV_ID}}", + "counterPartyAddress": "{{COUNTERPARTY_DOMAIN}}/dsp/2025-1", + "counterPartyId": "{{COUNTERPARTY_ID}}", "protocol": "dataspace-protocol-http:2025-1" } } diff --git a/bruno/single-node/transactions/provider/CreateAsset.bru b/bruno/single-node/transactions/provider/CreateAsset.bru index df3fea6..feaadee 100644 --- a/bruno/single-node/transactions/provider/CreateAsset.bru +++ b/bruno/single-node/transactions/provider/CreateAsset.bru @@ -5,9 +5,15 @@ meta { } post { - url: {{PROVIDER_MANAGEMENT}}/v3/assets + url: {{MANAGEMENT}}/v3/assets body: json - auth: inherit + auth: apikey +} + +auth:apikey { + key: X-Api-key + value: {{MANAGEMENT_API_KEY}} + placement: header } body:json { diff --git a/bruno/single-node/transactions/provider/CreateContractDefinition.bru b/bruno/single-node/transactions/provider/CreateContractDefinition.bru index e7b3b06..14378f4 100644 --- a/bruno/single-node/transactions/provider/CreateContractDefinition.bru +++ b/bruno/single-node/transactions/provider/CreateContractDefinition.bru @@ -5,9 +5,15 @@ meta { } post { - url: {{PROVIDER_MANAGEMENT}}/v3/contractdefinitions + url: {{MANAGEMENT}}/v3/contractdefinitions body: json - auth: inherit + auth: apikey +} + +auth:apikey { + key: X-Api-key + value: {{MANAGEMENT_API_KEY}} + placement: header } body:json { diff --git a/bruno/single-node/transactions/provider/CreatePolicy.bru b/bruno/single-node/transactions/provider/CreatePolicy.bru index ede9c2a..faf27ee 100644 --- a/bruno/single-node/transactions/provider/CreatePolicy.bru +++ b/bruno/single-node/transactions/provider/CreatePolicy.bru @@ -5,7 +5,7 @@ meta { } post { - url: {{PROVIDER_MANAGEMENT}}/v3/policydefinitions + url: {{MANAGEMENT}}/v3/policydefinitions body: json auth: inherit } diff --git a/docker/single-node/README.md b/docker/single-node/README.md index 0ace5c4..5c2b599 100644 --- a/docker/single-node/README.md +++ b/docker/single-node/README.md @@ -83,7 +83,7 @@ Sample output: ### Initialize Vault (only once) -`docker compose -f ./connector/docker-compose.yaml --env-file ./.env up shared-vault -d` +`docker compose -f ./connector/docker-compose.yaml --env-file ./.env up vault -d` #### Set the appropriate ownership The default Vault user inside the Container has the UID `100`. @@ -92,7 +92,7 @@ The default Vault user inside the Container has the UID `100`. #### Open a Terminal inside the Container -`docker exec -it shared-vault sh` +`docker exec -it vault sh` Run the following command inside the vault container: @@ -118,7 +118,7 @@ Run the following command with the unseal key from the previous step. #### Stop Vault -`docker compose -f ./connector/docker-compose.yaml --env-file ./.env down shared-vault -v` +`docker compose -f ./connector/docker-compose.yaml --env-file ./.env down vault -v` Your Vault is now initialized. @@ -127,7 +127,7 @@ Your Vault is now initialized. #### Open a Terminal inside the Container -`docker exec -it shared-vault sh` +`docker exec -it vault sh` #### Unseal Vault Run the following command with the unseal key. diff --git a/docker/single-node/connector/additional_config/pg_init/pg_init.sql b/docker/single-node/connector/additional_config/pg_init/pg_init.sql index c9d2ec8..e805d32 100644 --- a/docker/single-node/connector/additional_config/pg_init/pg_init.sql +++ b/docker/single-node/connector/additional_config/pg_init/pg_init.sql @@ -1,4 +1,4 @@ - CREATE DATABASE prov_ih_db; - CREATE DATABASE prov_cpl; - CREATE DATABASE prov_dpl; + CREATE DATABASE ih_db; + CREATE DATABASE cpl; + CREATE DATABASE dpl; diff --git a/docker/single-node/connector/additional_config/vault-init.sh b/docker/single-node/connector/additional_config/vault-init.sh index 43b8921..412f4a4 100644 --- a/docker/single-node/connector/additional_config/vault-init.sh +++ b/docker/single-node/connector/additional_config/vault-init.sh @@ -20,7 +20,7 @@ # SPDX-License-Identifier: Apache-2.0 # -VAULT="${VAULT_ADDR:-http://shared-vault:8200}" +VAULT="${VAULT_ADDR:-http://vault:8200}" TOKEN="${VAULT_TOKEN:?missing VAULT_TOKEN}" secret_exists() { @@ -60,9 +60,9 @@ create_and_store_keypair() { rm -f /tmp/${prefix}_priv_pkcs1.pem /tmp/${prefix}_priv.pem /tmp/${prefix}_pub.pem } -# create keypair for consumer and provider dataplane: +# create keypair for dataplane: -create_and_store_keypair "prov" +create_and_store_keypair "keyalias" create_and_store_aes_key() { local prefix=$1 @@ -89,5 +89,5 @@ create_and_store_aes_key() { echo "AES key stored at secret/data/${prefix}-aes-key-alias" } -# create AES keys for wallets -create_and_store_aes_key "provider-wallet" \ No newline at end of file +# create AES key for wallet +create_and_store_aes_key "wallet" \ No newline at end of file diff --git a/docker/single-node/connector/docker-compose-memory.yaml b/docker/single-node/connector/docker-compose-memory.yaml index d7ac47e..6b38790 100644 --- a/docker/single-node/connector/docker-compose-memory.yaml +++ b/docker/single-node/connector/docker-compose-memory.yaml @@ -19,8 +19,8 @@ # services: - shared-postgres: - container_name: shared-postgres + postgres: + container_name: postgres image: postgres:16.4-alpine environment: - POSTGRES_USER=admin @@ -35,8 +35,8 @@ services: networks: - con-x-test-network - shared-vault: - container_name: shared-vault + vault: + container_name: vault image: vault:1.13.3 command: server -dev -dev-root-token-id=vaultsecret0123456789 -dev-listen-address=0.0.0.0:8200 environment: @@ -60,8 +60,8 @@ services: # Note: When using Vault Mock, change the `vault-init` dependency from # `condition: service_healthy` to `condition: service_started`. - # shared-vault: - # container_name: shared-vault + # vault: + # container_name: vault # image: ghcr.io/project-construct-x/vault-mock:sha-efcc804 # environment: # HASHIMOCK_TOKEN: vaultsecret0123456789 @@ -75,11 +75,11 @@ services: container_name: vault-init image: alpine:3.19 depends_on: - shared-vault: + vault: # condition: service_healthy condition: service_started environment: - VAULT_ADDR: http://shared-vault:8200 + VAULT_ADDR: http://vault:8200 VAULT_TOKEN: vaultsecret0123456789 volumes: - ./additional_config/vault-init.sh:/scripts/init.sh:ro @@ -94,12 +94,12 @@ services: networks: - con-x-test-network - provider-wallet: - container_name: provider-wallet + wallet: + container_name: wallet image: ghcr.io/project-construct-x/wallet:0.17.0-1 pull_policy: missing depends_on: - shared-postgres: + postgres: condition: service_healthy vault-init: condition: service_completed_successfully @@ -120,16 +120,16 @@ services: - EDC_IH_API_SUPERUSER_ID=admin - EDC_IH_API_KEY_SUPERUSER=YWRtaW4.adminKey - EDC_ISSUER_STATUSLIST_SIGNING_KEY_ALIAS=foo - - EDC_ENCRYPTION_AES_KEY_ALIAS=provider-wallet-aes-key-alias + - EDC_ENCRYPTION_AES_KEY_ALIAS=wallet-aes-key-alias - EDC_IAM_KEY_ALGORITHM=RSA - EDC_IH_API_SUPERUSER_PUBLIC_KEY_ALIAS=admin3#pubkey - EDC_IH_API_SUPERUSER_PRIVATE_KEY_ALIAS=admin3#privkey - WEB_HTTP_DID_PORT=80 - EDC_SQL_SCHEMA_AUTOCREATE=true - - EDC_DATASOURCE_DEFAULT_URL=jdbc:postgresql://shared-postgres:5432/prov_ih_db + - EDC_DATASOURCE_DEFAULT_URL=jdbc:postgresql://postgres:5432/ih_db - EDC_DATASOURCE_DEFAULT_USER=admin - EDC_DATASOURCE_DEFAULT_PASSWORD=password - - EDC_VAULT_HASHICORP_URL=http://shared-vault:8200 + - EDC_VAULT_HASHICORP_URL=http://vault:8200 - EDC_VAULT_HASHICORP_HEALTH_CHECK_ENABLED=true - EDC_VAULT_HASHICORP_TOKEN=vaultsecret0123456789 - EDC_STATUSLIST_CALLBACK_ADDRESS=https://${DOMAIN}/statuslist @@ -137,8 +137,8 @@ services: - con-x-test-network - proxy - provider-controlplane: - container_name: provider-controlplane + controlplane: + container_name: controlplane image: ghcr.io/project-construct-x/con-x-controlplane-postgresql-hashicorp-vault:latest pull_policy: missing environment: @@ -157,16 +157,16 @@ services: - tx.edc.postgresql.migration.transferprocess.enabled=false - edc.iam.trusted-issuer.example.id=${ISSUER_DID} - edc.iam.did.web.use.https=true - - edc.iam.sts.oauth.client.secret.alias=consumersecret + - edc.iam.sts.oauth.client.secret.alias=vaultsecret - edc.iam.credential.revocation.mimetype=application/json - - edc.iam.sts.oauth.token.url=http://provider-wallet:9292/api/sts/token + - edc.iam.sts.oauth.token.url=http://wallet:9292/api/sts/token - edc.iam.sts.oauth.client.id=${DID} - edc.iam.issuer.id=${DID} - web.http.port=9000 - web.http.path=/api - web.http.management.port=9010 - web.http.management.path=/management - - web.http.management.auth.key=prov-management-api-key + - web.http.management.auth.key=management-api-key - web.http.management.auth.type=tokenbased - web.http.protocol.port=9020 - web.http.protocol.path=/dsp @@ -178,10 +178,10 @@ services: - edc.participant.id=${DID} - edc.dsp.callback.address=https://${DOMAIN}/dsp - edc.sql.schema.autocreate=true - - edc.datasource.default.url=jdbc:postgresql://shared-postgres:5432/prov_cpl + - edc.datasource.default.url=jdbc:postgresql://postgres:5432/cpl - edc.datasource.default.user=admin - edc.datasource.default.password=password - - edc.vault.hashicorp.url=http://shared-vault:8200 + - edc.vault.hashicorp.url=http://vault:8200 - edc.vault.hashicorp.health.check.enabled=true - edc.vault.hashicorp.token=vaultsecret0123456789 - tx.edc.iam.iatp.default-scopes.test.alias=org.eclipse.dspace.dcp.vc.type @@ -193,7 +193,7 @@ services: interval: 3s retries: 30 depends_on: - shared-postgres: + postgres: condition: service_healthy vault-init: condition: service_completed_successfully @@ -207,8 +207,8 @@ services: - con-x-test-network - proxy - provider-dataplane: - container_name: provider-dataplane + dataplane: + container_name: dataplane image: ghcr.io/project-construct-x/con-x-dataplane-postgresql-hashicorp-vault:latest pull_policy: missing environment: @@ -219,28 +219,28 @@ services: - web.http.management.path=/management - web.http.control.port=9550 - web.http.control.path=/dpcontrol - - edc.hostname=provider-dataplane + - edc.hostname=dataplane - edc.dpf.selector.url=https://${DOMAIN}/cpcontrol/v1/dataplanes - edc.data.plane.self.unregistration=true - - edc.datasource.default.url=jdbc:postgresql://shared-postgres:5432/prov_dpl + - edc.datasource.default.url=jdbc:postgresql://postgres:5432/dpl - edc.datasource.default.user=admin - edc.datasource.default.password=password - edc.sql.schema.autocreate=true - - edc.transfer.proxy.token.signer.privatekey.alias=prov_priv - - edc.transfer.proxy.token.verifier.publickey.alias=prov_pub - - edc.vault.hashicorp.url=http://shared-vault:8200 + - edc.transfer.proxy.token.signer.privatekey.alias=keyalias_priv + - edc.transfer.proxy.token.verifier.publickey.alias=keyalias_pub + - edc.vault.hashicorp.url=http://vault:8200 - edc.vault.hashicorp.health.check.enabled=true - edc.vault.hashicorp.token=vaultsecret0123456789 - edc.iam.trusted-issuer.example.id=${ISSUER_DID} - edc.iam.did.web.use.https=true - - edc.iam.sts.oauth.client.secret.alias=consumersecret + - edc.iam.sts.oauth.client.secret.alias=vaultsecret - edc.iam.credential.revocation.mimetype=application/json - - edc.iam.sts.oauth.token.url=http://provider-wallet:9292/api/sts/token + - edc.iam.sts.oauth.token.url=http://wallet:9292/api/sts/token - edc.iam.sts.oauth.client.id=${DID} - edc.iam.issuer.id=${DID} - edc.dataplane.api.public.baseurl=https://${DOMAIN}/public depends_on: - provider-controlplane: + controlplane: condition: service_healthy entrypoint: [ "java", "-jar", "edc-runtime.jar", "--log-level=DEBUG" ] ports: diff --git a/docker/single-node/connector/docker-compose.yaml b/docker/single-node/connector/docker-compose.yaml index f4d4092..4c0ae40 100644 --- a/docker/single-node/connector/docker-compose.yaml +++ b/docker/single-node/connector/docker-compose.yaml @@ -19,8 +19,8 @@ # services: - shared-postgres: - container_name: shared-postgres + postgres: + container_name: postgres image: postgres:16.4-alpine environment: - POSTGRES_USER=admin @@ -36,8 +36,8 @@ services: networks: - con-x-test-network - shared-vault: - container_name: shared-vault + vault: + container_name: vault image: vault:1.13.3 # image: vault:1.21 command: vault server -config=/vault/config/vault.hcl @@ -65,10 +65,10 @@ services: container_name: vault-init image: alpine:3.19 depends_on: - shared-vault: + vault: condition: service_healthy environment: - VAULT_ADDR: http://shared-vault:8200 + VAULT_ADDR: http://vault:8200 VAULT_TOKEN: ${VAULT_TOKEN} volumes: - ./additional_config/vault-init.sh:/scripts/init.sh:ro @@ -83,12 +83,12 @@ services: networks: - con-x-test-network - provider-wallet: - container_name: provider-wallet + wallet: + container_name: wallet image: ghcr.io/project-construct-x/wallet:0.17.0-1 pull_policy: missing depends_on: - shared-postgres: + postgres: condition: service_healthy vault-init: condition: service_completed_successfully @@ -111,16 +111,16 @@ services: - EDC_IH_API_SUPERUSER_ID=admin - EDC_IH_API_KEY_SUPERUSER=YWRtaW4.adminKey - EDC_ISSUER_STATUSLIST_SIGNING_KEY_ALIAS=foo - - EDC_ENCRYPTION_AES_KEY_ALIAS=provider-wallet-aes-key-alias + - EDC_ENCRYPTION_AES_KEY_ALIAS=wallet-aes-key-alias - EDC_IAM_KEY_ALGORITHM=RSA - EDC_IH_API_SUPERUSER_PUBLIC_KEY_ALIAS=admin3#pubkey - EDC_IH_API_SUPERUSER_PRIVATE_KEY_ALIAS=admin3#privkey - WEB_HTTP_DID_PORT=80 - EDC_SQL_SCHEMA_AUTOCREATE=true - - EDC_DATASOURCE_DEFAULT_URL=jdbc:postgresql://shared-postgres:5432/prov_ih_db + - EDC_DATASOURCE_DEFAULT_URL=jdbc:postgresql://postgres:5432/ih_db - EDC_DATASOURCE_DEFAULT_USER=admin - EDC_DATASOURCE_DEFAULT_PASSWORD=password - - EDC_VAULT_HASHICORP_URL=http://shared-vault:8200 + - EDC_VAULT_HASHICORP_URL=http://vault:8200 - EDC_VAULT_HASHICORP_HEALTH_CHECK_ENABLED=true - EDC_VAULT_HASHICORP_TOKEN=${VAULT_TOKEN} - EDC_STATUSLIST_CALLBACK_ADDRESS=https://${DOMAIN}/statuslist @@ -128,8 +128,8 @@ services: - con-x-test-network - proxy - provider-controlplane: - container_name: provider-controlplane + controlplane: + container_name: controlplane image: ghcr.io/project-construct-x/con-x-controlplane-postgresql-hashicorp-vault:latest pull_policy: missing environment: @@ -148,16 +148,16 @@ services: - tx.edc.postgresql.migration.transferprocess.enabled=false - edc.iam.trusted-issuer.example.id=${ISSUER_DID} - edc.iam.did.web.use.https=true - - edc.iam.sts.oauth.client.secret.alias=consumersecret + - edc.iam.sts.oauth.client.secret.alias=vaultsecret - edc.iam.credential.revocation.mimetype=application/json - - edc.iam.sts.oauth.token.url=http://provider-wallet:9292/api/sts/token + - edc.iam.sts.oauth.token.url=http://wallet:9292/api/sts/token - edc.iam.sts.oauth.client.id=${DID} - edc.iam.issuer.id=${DID} - web.http.port=9000 - web.http.path=/api - web.http.management.port=9010 - web.http.management.path=/management - - web.http.management.auth.key=prov-management-api-key + - web.http.management.auth.key=management-api-key - web.http.management.auth.type=tokenbased - web.http.protocol.port=9020 - web.http.protocol.path=/dsp @@ -169,10 +169,10 @@ services: - edc.participant.id=${DID} - edc.dsp.callback.address=https://${DOMAIN}/dsp - edc.sql.schema.autocreate=true - - edc.datasource.default.url=jdbc:postgresql://shared-postgres:5432/prov_cpl + - edc.datasource.default.url=jdbc:postgresql://postgres:5432/cpl - edc.datasource.default.user=admin - edc.datasource.default.password=password - - edc.vault.hashicorp.url=http://shared-vault:8200 + - edc.vault.hashicorp.url=http://vault:8200 - edc.vault.hashicorp.health.check.enabled=true - edc.vault.hashicorp.token=${VAULT_TOKEN} - tx.edc.iam.iatp.default-scopes.test.alias=org.eclipse.dspace.dcp.vc.type @@ -185,7 +185,7 @@ services: interval: 3s retries: 30 depends_on: - shared-postgres: + postgres: condition: service_healthy vault-init: condition: service_completed_successfully @@ -199,8 +199,8 @@ services: - con-x-test-network - proxy - provider-dataplane: - container_name: provider-dataplane + dataplane: + container_name: dataplane image: ghcr.io/project-construct-x/con-x-dataplane-postgresql-hashicorp-vault:latest pull_policy: missing environment: @@ -211,29 +211,29 @@ services: - web.http.management.path=/management - web.http.control.port=9550 - web.http.control.path=/dpcontrol - - edc.hostname=provider-dataplane + - edc.hostname=dataplane - edc.dpf.selector.url=https://${DOMAIN}/cpcontrol/v1/dataplanes - edc.data.plane.self.unregistration=true - - edc.datasource.default.url=jdbc:postgresql://shared-postgres:5432/prov_dpl + - edc.datasource.default.url=jdbc:postgresql://postgres:5432/dpl - edc.datasource.default.user=admin - edc.datasource.default.password=password - edc.sql.schema.autocreate=true - - edc.transfer.proxy.token.signer.privatekey.alias=prov_priv - - edc.transfer.proxy.token.verifier.publickey.alias=prov_pub - - edc.vault.hashicorp.url=http://shared-vault:8200 + - edc.transfer.proxy.token.signer.privatekey.alias=keyalias_priv + - edc.transfer.proxy.token.verifier.publickey.alias=keyalias_pub + - edc.vault.hashicorp.url=http://vault:8200 - edc.vault.hashicorp.health.check.enabled=true - edc.vault.hashicorp.token=${VAULT_TOKEN} - edc.iam.trusted-issuer.example.id=${ISSUER_DID} - edc.iam.did.web.use.https=true - - edc.iam.sts.oauth.client.secret.alias=consumersecret + - edc.iam.sts.oauth.client.secret.alias=vaultsecret - edc.iam.credential.revocation.mimetype=application/json - - edc.iam.sts.oauth.token.url=http://provider-wallet:9292/api/sts/token + - edc.iam.sts.oauth.token.url=http://wallet:9292/api/sts/token - edc.iam.sts.oauth.client.id=${DID} - edc.iam.issuer.id=${DID} - edc.dataplane.api.public.baseurl=https://${DOMAIN}/public - edc.vault.hashicorp.token.scheduled-renew-enabled=false depends_on: - provider-controlplane: + controlplane: condition: service_healthy entrypoint: [ "java", "-jar", "edc-runtime.jar", "--log-level=DEBUG" ] ports: diff --git a/docker/single-node/traefik/traefik-dynamic-conf.yaml b/docker/single-node/traefik/traefik-dynamic-conf.yaml index 2c9ee44..be47f12 100644 --- a/docker/single-node/traefik/traefik-dynamic-conf.yaml +++ b/docker/single-node/traefik/traefik-dynamic-conf.yaml @@ -141,62 +141,62 @@ http: dataplane-public-api-svc: loadBalancer: servers: - - url: http://provider-dataplane:9500 + - url: http://dataplane:9500 controlplane-management-api-svc: loadBalancer: servers: - - url: http://provider-controlplane:9010 + - url: http://controlplane:9010 controlplane-dsp-api-svc: loadBalancer: servers: - - url: http://provider-controlplane:9020 + - url: http://controlplane:9020 controlplane-cpcontrol-api-svc: loadBalancer: servers: - - url: http://provider-controlplane:9050 + - url: http://controlplane:9050 dataplane-dpcontrol-api-svc: loadBalancer: servers: - - url: http://provider-dataplane:9550 + - url: http://dataplane:9550 idhub-did-api-svc: loadBalancer: servers: - - url: http://provider-wallet:80 + - url: http://wallet:80 idhub-identity-api-svc: loadBalancer: servers: - - url: http://provider-wallet:15151 + - url: http://wallet:15151 idhub-sts-api-svc: loadBalancer: servers: - - url: http://provider-wallet:9292 + - url: http://wallet:9292 idhub-credentials-api-svc: loadBalancer: servers: - - url: http://provider-wallet:13131 + - url: http://wallet:13131 idhub-statuslist-api-svc: loadBalancer: servers: - - url: http://provider-wallet:9999 + - url: http://wallet:9999 issuance-api-svc: loadBalancer: servers: - - url: http://provider-wallet:13132 + - url: http://wallet:13132 issuer-api-svc: loadBalancer: servers: - - url: http://provider-wallet:15152 + - url: http://wallet:15152 # debug-svc: @@ -207,4 +207,4 @@ http: vault-svc: loadBalancer: servers: - - url: http://shared-vault:8200 \ No newline at end of file + - url: http://vault:8200 \ No newline at end of file From 3a9cbf70d012bd92fe7bf4e1cd9b8b5f8d7e7ccb Mon Sep 17 00:00:00 2001 From: Simon Malok Date: Thu, 20 Aug 2026 12:13:32 +0200 Subject: [PATCH 8/9] Remove unnecessary host port mappings --- docker/single-node/README.md | 6 ++++ .../connector/docker-compose-memory.yaml | 32 ++++++++----------- .../single-node/connector/docker-compose.yaml | 28 +++++++--------- .../traefik/traefik-dynamic-conf.yaml | 2 +- 4 files changed, 33 insertions(+), 35 deletions(-) diff --git a/docker/single-node/README.md b/docker/single-node/README.md index 5c2b599..5f981c0 100644 --- a/docker/single-node/README.md +++ b/docker/single-node/README.md @@ -81,6 +81,12 @@ Sample output: ## EDC +### Security Disclaimer + +For convenience, this setup exposes the Vault via a route so that the provided Bruno collection can access secrets and client credentials directly. This configuration is intended for development and testing environments only. + +If you do not want the Vault to be externally accessible, remove the Vault route and provide the required secrets through an alternative secure method. + ### Initialize Vault (only once) `docker compose -f ./connector/docker-compose.yaml --env-file ./.env up vault -d` diff --git a/docker/single-node/connector/docker-compose-memory.yaml b/docker/single-node/connector/docker-compose-memory.yaml index 6b38790..d0572a5 100644 --- a/docker/single-node/connector/docker-compose-memory.yaml +++ b/docker/single-node/connector/docker-compose-memory.yaml @@ -49,7 +49,7 @@ services: timeout: 3s retries: 20 ports: - - "8200:8200" + - "8200" networks: - con-x-test-network - proxy @@ -65,8 +65,6 @@ services: # image: ghcr.io/project-construct-x/vault-mock:sha-efcc804 # environment: # HASHIMOCK_TOKEN: vaultsecret0123456789 - # ports: - # - "8200:8200" # networks: # - con-x-test-network # - proxy @@ -76,8 +74,8 @@ services: image: alpine:3.19 depends_on: vault: - # condition: service_healthy - condition: service_started + condition: service_healthy + # condition: service_started environment: VAULT_ADDR: http://vault:8200 VAULT_TOKEN: vaultsecret0123456789 @@ -104,13 +102,11 @@ services: vault-init: condition: service_completed_successfully ports: - - "1046:1045" # debugger - - "21000:80" # did API -> / - - "21100:15151" # identity API -> /api/identity - - "21500:9292" # sts API -> /api/sts - - "21600:13131" # credentials API -> /api/credentials - # - "8181:8181" # default API -> /api - # - "9999:9999" # statuslist API -> /statuslist + # - "1045" # debugger + - "80" # did API -> / + - "15151" # identity API -> /api/identity + - "9292" # sts API -> /api/sts + - "13131" # credentials API -> /api/credentials environment: - JAVA_TOOL_OPTIONS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:1045 - EDC_HOSTNAME=${DOMAIN} @@ -199,10 +195,10 @@ services: condition: service_completed_successfully entrypoint: [ "java", "-jar", "edc-runtime.jar", "--log-level=DEBUG" ] ports: - - "5006:5005" # Debugger - - "39000:9000" # Default port - - "39010:9010" # Management API - - "39020:9020" # DSP API + # - "5005" # Debugger + - "9000" # Default port + - "9010" # Management API + - "9020" # DSP API networks: - con-x-test-network - proxy @@ -244,8 +240,8 @@ services: condition: service_healthy entrypoint: [ "java", "-jar", "edc-runtime.jar", "--log-level=DEBUG" ] ports: - - "5007:5005" # Debugger - - "9500:9500" # Public API + # - "5005" # Debugger + - "9500" # Public API networks: - con-x-test-network - proxy diff --git a/docker/single-node/connector/docker-compose.yaml b/docker/single-node/connector/docker-compose.yaml index 4c0ae40..3ded815 100644 --- a/docker/single-node/connector/docker-compose.yaml +++ b/docker/single-node/connector/docker-compose.yaml @@ -56,7 +56,7 @@ services: timeout: 3s retries: 20 ports: - - "8200:8200" + - "8200" networks: - con-x-test-network - proxy @@ -93,15 +93,11 @@ services: vault-init: condition: service_completed_successfully ports: - - "1046:1045" # debugger - - "21000:80" # did API -> / - - "21100:15151" # identity API -> /api/identity - - "21500:9292" # sts API -> /api/sts - - "21600:13131" # credentials API -> /api/credentials - # - "10200:15152" # issueradmin API -> /api/issuer - # - "13132:13132" # issuance API -> /api/issuance - # - "8181:8181" # default API -> /api - # - "9999:9999" # statuslist API -> /statuslist + # - "1045" # debugger + - "80" # did API -> / + - "15151" # identity API -> /api/identity + - "9292" # sts API -> /api/sts + - "13131" # credentials API -> /api/credentials environment: - JAVA_TOOL_OPTIONS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:1045 - EDC_HOSTNAME=${DOMAIN} @@ -191,10 +187,10 @@ services: condition: service_completed_successfully entrypoint: [ "java", "-jar", "edc-runtime.jar", "--log-level=DEBUG" ] ports: - - "5006:5005" # Debugger - - "39000:9000" # Default port - - "39010:9010" # Management API - - "39020:9020" # DSP API + # - "5005" # Debugger + - "9000" # Default port + - "9010" # Management API + - "9020" # DSP API networks: - con-x-test-network - proxy @@ -237,8 +233,8 @@ services: condition: service_healthy entrypoint: [ "java", "-jar", "edc-runtime.jar", "--log-level=DEBUG" ] ports: - - "5007:5005" # Debugger - - "9500:9500" # Public API + # - "5005" # Debugger + - "9500" # Public API networks: - con-x-test-network - proxy diff --git a/docker/single-node/traefik/traefik-dynamic-conf.yaml b/docker/single-node/traefik/traefik-dynamic-conf.yaml index be47f12..2a7e7e0 100644 --- a/docker/single-node/traefik/traefik-dynamic-conf.yaml +++ b/docker/single-node/traefik/traefik-dynamic-conf.yaml @@ -126,7 +126,7 @@ http: # tls: # certresolver: edc-resolver - vault-ui: + vault: entrypoints: - web - websecure From c2ff9f3f4bec0987a6605089707e14bd89be4116 Mon Sep 17 00:00:00 2001 From: Simon Malok Date: Thu, 20 Aug 2026 12:22:57 +0200 Subject: [PATCH 9/9] Add missing Auth in Bruno Collection --- bruno/single-node/transactions/provider/CreatePolicy.bru | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/bruno/single-node/transactions/provider/CreatePolicy.bru b/bruno/single-node/transactions/provider/CreatePolicy.bru index faf27ee..56ab974 100644 --- a/bruno/single-node/transactions/provider/CreatePolicy.bru +++ b/bruno/single-node/transactions/provider/CreatePolicy.bru @@ -7,7 +7,13 @@ meta { post { url: {{MANAGEMENT}}/v3/policydefinitions body: json - auth: inherit + auth: apikey +} + +auth:apikey { + key: X-Api-key + value: {{MANAGEMENT_API_KEY}} + placement: header } body:json {