diff --git a/buildspec.yml b/buildspec.yml new file mode 100644 index 000000000..dde83314f --- /dev/null +++ b/buildspec.yml @@ -0,0 +1,34 @@ +version: 0.2 + +phases: + pre_build: + commands: + - AWS_REGION="eu-west-1" + - COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-8) + - ECR_IMAGE_CATALOG_SERVER=${REPOSITORY_URI}/kordat-$ENV-catalog-server:${COMMIT_HASH} + - ECR_IMAGE_CONTROLPLANE=${REPOSITORY_URI}/kordat-$ENV-controlplane:${COMMIT_HASH} + - ECR_IMAGE_DATAPLANE=${REPOSITORY_URI}/kordat-$ENV-dataplane:${COMMIT_HASH} + - ECR_IMAGE_IDENTITY_HUB=${REPOSITORY_URI}/kordat-$ENV-identity-hub:${COMMIT_HASH} + - ECR_IMAGE_ISSUERSERVICE=${REPOSITORY_URI}/kordat-$ENV-issuerservice:${COMMIT_HASH} + - echo "Conectando con ECR..." + - aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $REPOSITORY_URI + - gradle --version || echo "Gradle no está instalado" + build: + commands: + - ./gradlew build + - ./gradlew -Ppersistence=true dockerize + - docker images + post_build: + commands: + - echo "Tagging images..." + - docker tag controlplane:latest $ECR_IMAGE_CONTROLPLANE + - docker tag dataplane:latest $ECR_IMAGE_DATAPLANE + - docker tag identity-hub:latest $ECR_IMAGE_IDENTITY_HUB + - docker tag catalog-server:latest $ECR_IMAGE_CATALOG_SERVER + - docker tag issuerservice:latest $ECR_IMAGE_ISSUERSERVICE + - echo "Pushing images..." + - docker push $ECR_IMAGE_CONTROLPLANE + - docker push $ECR_IMAGE_DATAPLANE + - docker push $ECR_IMAGE_IDENTITY_HUB + - docker push $ECR_IMAGE_CATALOG_SERVER + - docker push $ECR_IMAGE_ISSUERSERVICE diff --git a/connector-deployment/assets/consumer_private.pem b/connector-deployment/assets/consumer_private.pem new file mode 100644 index 000000000..81c28bac2 --- /dev/null +++ b/connector-deployment/assets/consumer_private.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIARDUGJgKy1yzxkueIJ1k3MPUWQ/tbQWQNqW6TjyHpdcoAoGCCqGSM49 +AwEHoUQDQgAE1l0Lof0a1yBc8KXhesAnoBvxZw5roYnkAXuqCYfNK3ex+hMWFuiX +GUxHlzShAehR6wvwzV23bbC0tcFcVgW//A== +-----END EC PRIVATE KEY----- \ No newline at end of file diff --git a/connector-deployment/assets/consumer_public.pem b/connector-deployment/assets/consumer_public.pem new file mode 100644 index 000000000..977a19576 --- /dev/null +++ b/connector-deployment/assets/consumer_public.pem @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1l0Lof0a1yBc8KXhesAnoBvxZw5r +oYnkAXuqCYfNK3ex+hMWFuiXGUxHlzShAehR6wvwzV23bbC0tcFcVgW//A== +-----END PUBLIC KEY----- \ No newline at end of file diff --git a/connector-deployment/assets/credentials/k8s/consumer/dataprocessor-credential.json b/connector-deployment/assets/credentials/k8s/consumer/dataprocessor-credential.json new file mode 100644 index 000000000..cd820a437 --- /dev/null +++ b/connector-deployment/assets/credentials/k8s/consumer/dataprocessor-credential.json @@ -0,0 +1,39 @@ +{ + "id": "40e24588-b510-41ca-966c-c1e0f57d1b15", + "participantContextId": "${did}", + "timestamp": 1700659822500, + "issuerId": "did:web:dataspace-issuer", + "holderId": "${did}", + "state": 500, + "issuancePolicy": null, + "reissuancePolicy": null, + "verifiableCredential": { + "format": "VC1_0_JWT", + "rawVc": "eyJraWQiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIja2V5LTEiLCJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJpc3MiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIiLCJhdWQiOiJkaWQ6d2ViOmNvbnN1bWVyLWlkZW50aXR5aHViJTNBNzA4MzphbGljZSIsInN1YiI6ImRpZDp3ZWI6Y29uc3VtZXItaWRlbnRpdHlodWIlM0E3MDgzOmFsaWNlIiwidmMiOnsiQGNvbnRleHQiOlsiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvdjEiLCJodHRwczovL3czaWQub3JnL3NlY3VyaXR5L3N1aXRlcy9qd3MtMjAyMC92MSIsImh0dHBzOi8vd3d3LnczLm9yZy9ucy9kaWQvdjEiLHsibXZkLWNyZWRlbnRpYWxzIjoiaHR0cHM6Ly93M2lkLm9yZy9tdmQvY3JlZGVudGlhbHMvIiwiY29udHJhY3RWZXJzaW9uIjoibXZkLWNyZWRlbnRpYWxzOmNvbnRyYWN0VmVyc2lvbiIsImxldmVsIjoibXZkLWNyZWRlbnRpYWxzOmxldmVsIn1dLCJpZCI6Imh0dHA6Ly9vcmcueW91cmRhdGFzcGFjZS5jb20vY3JlZGVudGlhbHMvMjM0NyIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJEYXRhUHJvY2Vzc29yQ3JlZGVudGlhbCJdLCJpc3N1ZXIiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIiLCJpc3N1YW5jZURhdGUiOiIyMDIzLTA4LTE4VDAwOjAwOjAwWiIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOndlYjpjb25zdW1lci1pZGVudGl0eWh1YiUzQTcwODM6Y29uc3VtZXIiLCJjb250cmFjdFZlcnNpb24iOiIxLjAuMCIsImxldmVsIjoicHJvY2Vzc2luZyJ9fSwiaWF0IjoxNzQ4ODQ0OTE5fQ.Asd_5HEu-UaV3bSZ3DlkIlI5yiAik18JcAtKwK6HVx3MAW5uR907lEJfgdO29eHfTR9_qiHG5OitXYCpL_sxBQ", + "credential": { + "credentialSubject": [ + { + "claims": { + "id": "${did}", + "contractVersion": "1.0.0", + "level": "processing" + } + } + ], + "id": "http://org.yourdataspace.com/credentials/1235", + "type": [ + "VerifiableCredential", + "DataProcessorCredential" + ], + "issuer": { + "id": "did:web:dataspace-issuer", + "additionalProperties": {} + }, + "issuanceDate": 1702339200.000000000, + "expirationDate": null, + "credentialStatus": null, + "description": null, + "name": null + } + } +} diff --git a/connector-deployment/assets/credentials/k8s/consumer/dataprocessor_vc.json b/connector-deployment/assets/credentials/k8s/consumer/dataprocessor_vc.json new file mode 100644 index 000000000..1b9e7faac --- /dev/null +++ b/connector-deployment/assets/credentials/k8s/consumer/dataprocessor_vc.json @@ -0,0 +1,24 @@ +{ + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://w3id.org/security/suites/jws-2020/v1", + "https://www.w3.org/ns/did/v1", + { + "mvd-credentials": "https://w3id.org/mvd/credentials/", + "contractVersion": "mvd-credentials:contractVersion", + "level": "mvd-credentials:level" + } + ], + "id": "http://org.yourdataspace.com/credentials/2347", + "type": [ + "VerifiableCredential", + "DataProcessorCredential" + ], + "issuer": "did:web:dataspace-issuer", + "issuanceDate": "2023-08-18T00:00:00Z", + "credentialSubject": { + "id": "${did}", + "contractVersion": "1.0.0", + "level": "processing" + } +} \ No newline at end of file diff --git a/connector-deployment/assets/credentials/k8s/consumer/membership-credential.json b/connector-deployment/assets/credentials/k8s/consumer/membership-credential.json new file mode 100644 index 000000000..d3334ce58 --- /dev/null +++ b/connector-deployment/assets/credentials/k8s/consumer/membership-credential.json @@ -0,0 +1,41 @@ +{ + "id": "40e24588-b510-41ca-966c-c1e0f57d1b14", + "participantContextId": "${did}", + "timestamp": 1700659822500, + "issuerId": "did:web:dataspace-issuer", + "holderId": "${did}", + "state": 500, + "issuancePolicy": null, + "reissuancePolicy": null, + "verifiableCredential": { + "rawVc": "eyJraWQiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIja2V5LTEiLCJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJpc3MiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIiLCJhdWQiOiJkaWQ6d2ViOmNvbnN1bWVyLWlkZW50aXR5aHViJTNBNzA4MzphbGljZSIsInN1YiI6ImRpZDp3ZWI6Y29uc3VtZXItaWRlbnRpdHlodWIlM0E3MDgzOmFsaWNlIiwidmMiOnsiQGNvbnRleHQiOlsiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvdjEiLCJodHRwczovL3czaWQub3JnL3NlY3VyaXR5L3N1aXRlcy9qd3MtMjAyMC92MSIsImh0dHBzOi8vd3d3LnczLm9yZy9ucy9kaWQvdjEiLHsibXZkLWNyZWRlbnRpYWxzIjoiaHR0cHM6Ly93M2lkLm9yZy9tdmQvY3JlZGVudGlhbHMvIiwibWVtYmVyc2hpcCI6Im12ZC1jcmVkZW50aWFsczptZW1iZXJzaGlwIiwibWVtYmVyc2hpcFR5cGUiOiJtdmQtY3JlZGVudGlhbHM6bWVtYmVyc2hpcFR5cGUiLCJ3ZWJzaXRlIjoibXZkLWNyZWRlbnRpYWxzOndlYnNpdGUiLCJjb250YWN0IjoibXZkLWNyZWRlbnRpYWxzOmNvbnRhY3QiLCJzaW5jZSI6Im12ZC1jcmVkZW50aWFsczpzaW5jZSJ9XSwiaWQiOiJodHRwOi8vb3JnLnlvdXJkYXRhc3BhY2UuY29tL2NyZWRlbnRpYWxzLzIzNDciLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiTWVtYmVyc2hpcENyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOndlYjpkYXRhc3BhY2UtaXNzdWVyIiwiaXNzdWFuY2VEYXRlIjoiMjAyMy0wOC0xOFQwMDowMDowMFoiLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDp3ZWI6Y29uc3VtZXItaWRlbnRpdHlodWIlM0E3MDgzOmNvbnN1bWVyIiwibWVtYmVyc2hpcCI6eyJtZW1iZXJzaGlwVHlwZSI6IkZ1bGxNZW1iZXIiLCJ3ZWJzaXRlIjoid3d3LndoYXRldmVyLmNvbSIsImNvbnRhY3QiOiJmaXp6LmJ1enpAd2hhdGV2ZXIuY29tIiwic2luY2UiOiIyMDIzLTAxLTAxVDAwOjAwOjAwWiJ9fX0sImlhdCI6MTc0ODg0NDkxOX0.xcb9qKJ_BGGj_KvSM9lZIdJW01FSdDjALXxhmH8CehkOPy2nXGnWKIbjHJZmW60NtU7kqRC23THU7OWFs28EDw", + "format": "VC1_0_JWT", + "credential": { + "credentialSubject": [ + { + "claims": { + "membershipType": "FullMember", + "website": "www.some-other-website.com", + "contact": "bar.baz@company.com", + "since": "2023-01-01T00:00:00Z" + }, + "id": "${did}" + } + ], + "id": "http://org.yourdataspace.com/credentials/2347", + "type": [ + "VerifiableCredential", + "MembershipCredential" + ], + "issuer": { + "id": "did:web:dataspace-issuer", + "additionalProperties": {} + }, + "issuanceDate": 1702339200.000000000, + "expirationDate": null, + "credentialStatus": null, + "description": null, + "name": null + } + } +} diff --git a/connector-deployment/assets/credentials/k8s/consumer/membership_vc.json b/connector-deployment/assets/credentials/k8s/consumer/membership_vc.json new file mode 100644 index 000000000..1cf10b329 --- /dev/null +++ b/connector-deployment/assets/credentials/k8s/consumer/membership_vc.json @@ -0,0 +1,31 @@ +{ + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://w3id.org/security/suites/jws-2020/v1", + "https://www.w3.org/ns/did/v1", + { + "mvd-credentials": "https://w3id.org/mvd/credentials/", + "membership": "mvd-credentials:membership", + "membershipType": "mvd-credentials:membershipType", + "website": "mvd-credentials:website", + "contact": "mvd-credentials:contact", + "since": "mvd-credentials:since" + } + ], + "id": "http://org.yourdataspace.com/credentials/2347", + "type": [ + "VerifiableCredential", + "MembershipCredential" + ], + "issuer": "did:web:dataspace-issuer", + "issuanceDate": "2023-08-18T00:00:00Z", + "credentialSubject": { + "id": "${did}", + "membership": { + "membershipType": "FullMember", + "website": "www.whatever.com", + "contact": "fizz.buzz@whatever.com", + "since": "2023-01-01T00:00:00Z" + } + } +} \ No newline at end of file diff --git a/connector-deployment/assets/credentials/k8s/participant/dataprocessor-credential.json b/connector-deployment/assets/credentials/k8s/participant/dataprocessor-credential.json new file mode 100644 index 000000000..7cc5facf3 --- /dev/null +++ b/connector-deployment/assets/credentials/k8s/participant/dataprocessor-credential.json @@ -0,0 +1,39 @@ +{ + "id": "", + "participantContextId": "did:web:-identityhub.%3A7083:", + "timestamp": , + "issuerId": "did:web:dataspace-issuer", + "holderId": "did:web:-identityhub.%3A7083:", + "state": 500, + "issuancePolicy": null, + "reissuancePolicy": null, + "verifiableCredential": { + "format": "VC1_0_JWT", + "rawVc": "{{RAW_VC_JWT}}", + "credential": { + "credentialSubject": [ + { + "claims": { + "id": "did:web:-identityhub.%3A7083:", + "contractVersion": "1.0.0", + "level": "processing" + } + } + ], + "id": "http://kordat.es/credentials/", + "type": [ + "VerifiableCredential", + "DataProcessorCredential" + ], + "issuer": { + "id": "did:web:dataspace-issuer", + "additionalProperties": {} + }, + "issuanceDate": null, + "expirationDate": null, + "credentialStatus": null, + "description": null, + "name": null + } + } +} diff --git a/connector-deployment/assets/credentials/k8s/participant/dataprocessor_vc.json b/connector-deployment/assets/credentials/k8s/participant/dataprocessor_vc.json new file mode 100644 index 000000000..6ad853a64 --- /dev/null +++ b/connector-deployment/assets/credentials/k8s/participant/dataprocessor_vc.json @@ -0,0 +1,24 @@ +{ + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://w3id.org/security/suites/jws-2020/v1", + "https://www.w3.org/ns/did/v1", + { + "mvd-credentials": "https://w3id.org/mvd/credentials/", + "contractVersion": "mvd-credentials:contractVersion", + "level": "mvd-credentials:level" + } + ], + "id": "http://kordat.es/credentials/1235", + "type": [ + "VerifiableCredential", + "DataProcessorCredential" + ], + "issuer": "did:web:dataspace-issuer", + "issuanceDate": "2023-08-18T00:00:00Z", + "credentialSubject": { + "id": "did:web:-identityhub.%3A7083:", + "contractVersion": "1.0.0", + "level": "processing" + } +} diff --git a/connector-deployment/assets/credentials/k8s/participant/membership-credential.json b/connector-deployment/assets/credentials/k8s/participant/membership-credential.json new file mode 100644 index 000000000..9437b892a --- /dev/null +++ b/connector-deployment/assets/credentials/k8s/participant/membership-credential.json @@ -0,0 +1,41 @@ +{ + "id": "", + "participantContextId": "did:web:-identityhub.%3A7083:", + "timestamp": , + "issuerId": "did:web:dataspace-issuer", + "holderId": "did:web:-identityhub.%3A7083:", + "state": 500, + "issuancePolicy": null, + "reissuancePolicy": null, + "verifiableCredential": { + "format": "VC1_0_JWT", + "rawVc": "{{RAW_VC_JWT}}", + "credential": { + "credentialSubject": [ + { + "claims": { + "membershipType": "FullMember", + "website": "www.example.com", + "contact": "admin@example.com", + "since": "2023-01-01T00:00:00Z" + }, + "id": "did:web:-identityhub.%3A7083:" + } + ], + "id": "http://kordat.es/credentials/", + "type": [ + "VerifiableCredential", + "MembershipCredential" + ], + "issuer": { + "id": "{{DATASPACE_ISSUER_DID}}", + "additionalProperties": {} + }, + "issuanceDate": 1702339200.000000000, + "expirationDate": null, + "credentialStatus": null, + "description": null, + "name": null + } + } +} diff --git a/connector-deployment/assets/credentials/k8s/participant/membership_vc.json b/connector-deployment/assets/credentials/k8s/participant/membership_vc.json new file mode 100644 index 000000000..bdd7ce1da --- /dev/null +++ b/connector-deployment/assets/credentials/k8s/participant/membership_vc.json @@ -0,0 +1,31 @@ +{ + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://w3id.org/security/suites/jws-2020/v1", + "https://www.w3.org/ns/did/v1", + { + "mvd-credentials": "https://w3id.org/mvd/credentials/", + "membership": "mvd-credentials:membership", + "membershipType": "mvd-credentials:membershipType", + "website": "mvd-credentials:website", + "contact": "mvd-credentials:contact", + "since": "mvd-credentials:since" + } + ], + "id": "http://kordat.es/credentials/2347", + "type": [ + "VerifiableCredential", + "MembershipCredential" + ], + "issuer": "did:web:dataspace-issuer", + "issuanceDate": "2023-08-18T00:00:00Z", + "credentialSubject": { + "id": "did:web:-identityhub.%3A7083:", + "membership": { + "membershipType": "FullMember", + "website": "www.example.com", + "contact": "admin@example.com", + "since": "2023-01-01T00:00:00Z" + } + } +} diff --git a/connector-deployment/assets/credentials/k8s/provider/dataprocessor-credential.json b/connector-deployment/assets/credentials/k8s/provider/dataprocessor-credential.json new file mode 100644 index 000000000..7ed5bee2c --- /dev/null +++ b/connector-deployment/assets/credentials/k8s/provider/dataprocessor-credential.json @@ -0,0 +1,39 @@ +{ + "id": "40e24588-b510-41ca-966c-c1e0f57d1ca7", + "participantContextId": "did:web:provider-identityhub%3A7083:provider", + "timestamp": 1700659822500, + "issuerId": "did:web:dataspace-issuer", + "holderId": "did:web:provider-identityhub%3A7083:provider", + "state": 500, + "issuancePolicy": null, + "reissuancePolicy": null, + "verifiableCredential": { + "format": "VC1_0_JWT", + "rawVc": "eyJraWQiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIja2V5LTEiLCJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJpc3MiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIiLCJhdWQiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkZW50aXR5aHViJTNBNzA4Mzpib2IiLCJzdWIiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkZW50aXR5aHViJTNBNzA4Mzpib2IiLCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vdzNpZC5vcmcvc2VjdXJpdHkvc3VpdGVzL2p3cy0yMDIwL3YxIiwiaHR0cHM6Ly93d3cudzMub3JnL25zL2RpZC92MSIseyJtdmQtY3JlZGVudGlhbHMiOiJodHRwczovL3czaWQub3JnL212ZC9jcmVkZW50aWFscy8iLCJjb250cmFjdFZlcnNpb24iOiJtdmQtY3JlZGVudGlhbHM6Y29udHJhY3RWZXJzaW9uIiwibGV2ZWwiOiJtdmQtY3JlZGVudGlhbHM6bGV2ZWwifV0sImlkIjoiaHR0cDovL29yZy55b3VyZGF0YXNwYWNlLmNvbS9jcmVkZW50aWFscy8yMzQ3IiwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIkRhdGFQcm9jZXNzb3JDcmVkZW50aWFsIl0sImlzc3VlciI6ImRpZDp3ZWI6ZGF0YXNwYWNlLWlzc3VlciIsImlzc3VhbmNlRGF0ZSI6IjIwMjMtMDgtMThUMDA6MDA6MDBaIiwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkZW50aXR5aHViJTNBNzA4Mzpwcm92aWRlciIsImxldmVsIjoicHJvY2Vzc2luZyIsImNvbnRyYWN0VmVyc2lvbiI6IjEuMC4wIn19LCJpYXQiOjE3NDg4NDQ5MTl9.lgSIzaPA9mm1LTEssDlfG2bcKUyhjWfjl85yEMHcKxAjl3kyFw1lBSokCR85f2bm-ZBHiAfCh9M9W1jixjPTCg", + "credential": { + "credentialSubject": [ + { + "claims": { + "id": "did:web:provider-identityhub%3A7083:provider", + "contractVersion": "1.0.0", + "level": "processing" + } + } + ], + "id": "http://org.yourdataspace.com/credentials/1265", + "type": [ + "VerifiableCredential", + "DataProcessorCredential" + ], + "issuer": { + "id": "did:web:dataspace-issuer", + "additionalProperties": {} + }, + "issuanceDate": 1702339200.000000000, + "expirationDate": null, + "credentialStatus": null, + "description": null, + "name": null + } + } +} diff --git a/connector-deployment/assets/credentials/k8s/provider/dataprocessor_vc.json b/connector-deployment/assets/credentials/k8s/provider/dataprocessor_vc.json new file mode 100644 index 000000000..ff3160ebb --- /dev/null +++ b/connector-deployment/assets/credentials/k8s/provider/dataprocessor_vc.json @@ -0,0 +1,24 @@ +{ + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://w3id.org/security/suites/jws-2020/v1", + "https://www.w3.org/ns/did/v1", + { + "mvd-credentials": "https://w3id.org/mvd/credentials/", + "contractVersion": "mvd-credentials:contractVersion", + "level": "mvd-credentials:level" + } + ], + "id": "http://org.yourdataspace.com/credentials/2347", + "type": [ + "VerifiableCredential", + "DataProcessorCredential" + ], + "issuer": "did:web:dataspace-issuer", + "issuanceDate": "2023-08-18T00:00:00Z", + "credentialSubject": { + "id": "did:web:provider-identityhub%3A7083:provider", + "level": "processing", + "contractVersion": "1.0.0" + } +} \ No newline at end of file diff --git a/connector-deployment/assets/credentials/k8s/provider/membership-credential.json b/connector-deployment/assets/credentials/k8s/provider/membership-credential.json new file mode 100644 index 000000000..076ef60e0 --- /dev/null +++ b/connector-deployment/assets/credentials/k8s/provider/membership-credential.json @@ -0,0 +1,43 @@ +{ + "id": "40e24588-b510-41ca-966c-c1e0f57d1b14", + "participantContextId": "did:web:provider-identityhub%3A7083:provider", + "timestamp": 1700659822500, + "issuerId": "did:web:dataspace-issuer", + "holderId": "did:web:provider-identityhub%3A7083:provider", + "state": 500, + "issuancePolicy": null, + "reissuancePolicy": null, + "verifiableCredential": { + "rawVc": "eyJraWQiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIja2V5LTEiLCJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJpc3MiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIiLCJhdWQiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkZW50aXR5aHViJTNBNzA4Mzpib2IiLCJzdWIiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkZW50aXR5aHViJTNBNzA4Mzpib2IiLCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vdzNpZC5vcmcvc2VjdXJpdHkvc3VpdGVzL2p3cy0yMDIwL3YxIiwiaHR0cHM6Ly93d3cudzMub3JnL25zL2RpZC92MSIseyJtdmQtY3JlZGVudGlhbHMiOiJodHRwczovL3czaWQub3JnL212ZC9jcmVkZW50aWFscy8iLCJtZW1iZXJzaGlwIjoibXZkLWNyZWRlbnRpYWxzOm1lbWJlcnNoaXAiLCJtZW1iZXJzaGlwVHlwZSI6Im12ZC1jcmVkZW50aWFsczptZW1iZXJzaGlwVHlwZSIsIndlYnNpdGUiOiJtdmQtY3JlZGVudGlhbHM6d2Vic2l0ZSIsImNvbnRhY3QiOiJtdmQtY3JlZGVudGlhbHM6Y29udGFjdCIsInNpbmNlIjoibXZkLWNyZWRlbnRpYWxzOnNpbmNlIn1dLCJpZCI6Imh0dHA6Ly9vcmcueW91cmRhdGFzcGFjZS5jb20vY3JlZGVudGlhbHMvMjM0NyIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJNZW1iZXJzaGlwQ3JlZGVudGlhbCJdLCJpc3N1ZXIiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIiLCJpc3N1YW5jZURhdGUiOiIyMDIzLTA4LTE4VDAwOjAwOjAwWiIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOndlYjpwcm92aWRlci1pZGVudGl0eWh1YiUzQTcwODM6cHJvdmlkZXIiLCJtZW1iZXJzaGlwIjp7Im1lbWJlcnNoaXBUeXBlIjoiRnVsbE1lbWJlciIsIndlYnNpdGUiOiJ3d3cud2hhdGV2ZXIuY29tIiwiY29udGFjdCI6Im1peC5tYXhAd2hhdGV2ZXIuY29tIiwic2luY2UiOiIyMDIzLTAxLTAxVDAwOjAwOjAwWiJ9fX0sImlhdCI6MTc0ODg0NDkxOH0.iX84wIF6unwmOWPtyRHAYv-YaoDSTzHl1ioZcfa-Y6aMGzbgD4EDhjKY9syR5mdYYIvqs__cAN-d3MOKbMgjDA", + "format": "VC1_0_JWT", + "credential": { + "credentialSubject": [ + { + "claims": { + "membership": { + "membershipType": "FullMember", + "website": "www.company-website.com", + "contact": "max.mustermann@company.com", + "since": "2023-05-08T00:00:00Z" + } + }, + "id": "did:web:provider-identityhub%3A7083:provider" + } + ], + "id": "http://org.yourdataspace.com/credentials/1234", + "type": [ + "VerifiableCredential", + "MembershipCredential" + ], + "issuer": { + "id": "did:web:dataspace-issuer", + "additionalProperties": {} + }, + "issuanceDate": 1702339200.000000000, + "expirationDate": null, + "credentialStatus": null, + "description": null, + "name": null + } + } +} diff --git a/connector-deployment/assets/credentials/k8s/provider/membership_vc.json b/connector-deployment/assets/credentials/k8s/provider/membership_vc.json new file mode 100644 index 000000000..4cf4ec500 --- /dev/null +++ b/connector-deployment/assets/credentials/k8s/provider/membership_vc.json @@ -0,0 +1,31 @@ +{ + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://w3id.org/security/suites/jws-2020/v1", + "https://www.w3.org/ns/did/v1", + { + "mvd-credentials": "https://w3id.org/mvd/credentials/", + "membership": "mvd-credentials:membership", + "membershipType": "mvd-credentials:membershipType", + "website": "mvd-credentials:website", + "contact": "mvd-credentials:contact", + "since": "mvd-credentials:since" + } + ], + "id": "http://org.yourdataspace.com/credentials/2347", + "type": [ + "VerifiableCredential", + "MembershipCredential" + ], + "issuer": "did:web:dataspace-issuer", + "issuanceDate": "2023-08-18T00:00:00Z", + "credentialSubject": { + "id": "did:web:provider-identityhub%3A7083:provider", + "membership": { + "membershipType": "FullMember", + "website": "www.whatever.com", + "contact": "mix.max@whatever.com", + "since": "2023-01-01T00:00:00Z" + } + } +} \ No newline at end of file diff --git a/connector-deployment/assets/credentials/local/consumer/dataprocessor-credential.json b/connector-deployment/assets/credentials/local/consumer/dataprocessor-credential.json new file mode 100644 index 000000000..934f2d850 --- /dev/null +++ b/connector-deployment/assets/credentials/local/consumer/dataprocessor-credential.json @@ -0,0 +1,39 @@ +{ + "id": "40e24588-b510-41ca-966c-c1e0f57d1b15", + "participantContextId": "did:web:localhost%3A7083", + "timestamp": 1700659822500, + "issuerId": "did:web:localhost%3A9876", + "holderId": "did:web:localhost%3A7093", + "state": 500, + "issuancePolicy": null, + "reissuancePolicy": null, + "verifiableCredential": { + "format": "VC1_0_JWT", + "rawVc": "eyJraWQiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYja2V5LTEiLCJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJpc3MiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYiLCJhdWQiOiJkaWQ6d2ViOmNvbnN1bWVyLWlkZW50aXR5aHViJTNBNzA4MzphbGljZSIsInN1YiI6ImRpZDp3ZWI6Y29uc3VtZXItaWRlbnRpdHlodWIlM0E3MDgzOmFsaWNlIiwidmMiOnsiQGNvbnRleHQiOlsiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvdjEiLCJodHRwczovL3czaWQub3JnL3NlY3VyaXR5L3N1aXRlcy9qd3MtMjAyMC92MSIsImh0dHBzOi8vd3d3LnczLm9yZy9ucy9kaWQvdjEiLHsibXZkLWNyZWRlbnRpYWxzIjoiaHR0cHM6Ly93M2lkLm9yZy9tdmQvY3JlZGVudGlhbHMvIiwiY29udHJhY3RWZXJzaW9uIjoibXZkLWNyZWRlbnRpYWxzOmNvbnRyYWN0VmVyc2lvbiIsImxldmVsIjoibXZkLWNyZWRlbnRpYWxzOmxldmVsIn1dLCJpZCI6Imh0dHA6Ly9vcmcueW91cmRhdGFzcGFjZS5jb20vY3JlZGVudGlhbHMvMjM0NyIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJEYXRhUHJvY2Vzc29yQ3JlZGVudGlhbCJdLCJpc3N1ZXIiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYiLCJpc3N1YW5jZURhdGUiOiIyMDIzLTA4LTE4VDAwOjAwOjAwWiIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOndlYjpsb2NhbGhvc3QlM0E3MDgzIiwiY29udHJhY3RWZXJzaW9uIjoiMS4wLjAiLCJsZXZlbCI6InByb2Nlc3NpbmcifX0sImlhdCI6MTc0ODg0NDkxOX0.B3ZjHNsiOhuiv78uv4hu08LyA9gZrciMhKOHsC9CV99_KesoWQAjrsg2bJd2b3QQguLoR0C3S3u-9tcYvmB1Cg", + "credential": { + "credentialSubject": [ + { + "claims": { + "id": "did:web:localhost%3A7083", + "contractVersion": "1.0.0", + "level": "processing" + } + } + ], + "id": "http://org.yourdataspace.com/credentials/1235", + "type": [ + "VerifiableCredential", + "DataProcessorCredential" + ], + "issuer": { + "id": "did:web:localhost%3A9876", + "additionalProperties": {} + }, + "issuanceDate": 1702339200.000000000, + "expirationDate": null, + "credentialStatus": null, + "description": null, + "name": null + } + } +} diff --git a/connector-deployment/assets/credentials/local/consumer/membership-credential.json b/connector-deployment/assets/credentials/local/consumer/membership-credential.json new file mode 100644 index 000000000..95ce92cd9 --- /dev/null +++ b/connector-deployment/assets/credentials/local/consumer/membership-credential.json @@ -0,0 +1,41 @@ +{ + "id": "40e24588-b510-41ca-966c-c1e0f57d1b14", + "participantContextId": "did:web:localhost%3A7083", + "timestamp": 1700659822500, + "issuerId": "did:web:localhost%3A9876", + "holderId": "did:web:localhost%3A7083", + "state": 500, + "issuancePolicy": null, + "reissuancePolicy": null, + "verifiableCredential": { + "rawVc": "eyJraWQiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYja2V5LTEiLCJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJpc3MiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYiLCJhdWQiOiJkaWQ6d2ViOmNvbnN1bWVyLWlkZW50aXR5aHViJTNBNzA4MzphbGljZSIsInN1YiI6ImRpZDp3ZWI6Y29uc3VtZXItaWRlbnRpdHlodWIlM0E3MDgzOmFsaWNlIiwidmMiOnsiQGNvbnRleHQiOlsiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvdjEiLCJodHRwczovL3czaWQub3JnL3NlY3VyaXR5L3N1aXRlcy9qd3MtMjAyMC92MSIsImh0dHBzOi8vd3d3LnczLm9yZy9ucy9kaWQvdjEiLHsibXZkLWNyZWRlbnRpYWxzIjoiaHR0cHM6Ly93M2lkLm9yZy9tdmQvY3JlZGVudGlhbHMvIiwibWVtYmVyc2hpcCI6Im12ZC1jcmVkZW50aWFsczptZW1iZXJzaGlwIiwibWVtYmVyc2hpcFR5cGUiOiJtdmQtY3JlZGVudGlhbHM6bWVtYmVyc2hpcFR5cGUiLCJ3ZWJzaXRlIjoibXZkLWNyZWRlbnRpYWxzOndlYnNpdGUiLCJjb250YWN0IjoibXZkLWNyZWRlbnRpYWxzOmNvbnRhY3QiLCJzaW5jZSI6Im12ZC1jcmVkZW50aWFsczpzaW5jZSJ9XSwiaWQiOiJodHRwOi8vb3JnLnlvdXJkYXRhc3BhY2UuY29tL2NyZWRlbnRpYWxzLzIzNDciLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiTWVtYmVyc2hpcENyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOndlYjpsb2NhbGhvc3QlM0E5ODc2IiwiaXNzdWFuY2VEYXRlIjoiMjAyMy0wOC0xOFQwMDowMDowMFoiLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDp3ZWI6bG9jYWxob3N0JTNBNzA4MyIsIm1lbWJlcnNoaXAiOnsibWVtYmVyc2hpcFR5cGUiOiJGdWxsTWVtYmVyIiwid2Vic2l0ZSI6Ind3dy53aGF0ZXZlci5jb20iLCJjb250YWN0IjoibWl4Lm1heEB3aGF0ZXZlci5jb20iLCJzaW5jZSI6IjIwMjMtMDEtMDFUMDA6MDA6MDBaIn19fSwiaWF0IjoxNzQ4ODQ0OTE5fQ.xnb1qnjEUpSAzFlJT9krVkW8y7MffVJL7xhfimLEV2ADYtRw_94LvcYuv-eFwMcOEMtNzfWj4MRoM2IslI5rBw", + "format": "VC1_0_JWT", + "credential": { + "credentialSubject": [ + { + "claims": { + "membershipType": "FullMember", + "website": "www.some-other-website.com", + "contact": "bar.baz@company.com", + "since": "2023-01-01T00:00:00Z" + }, + "id": "did:web:localhost%3A7083" + } + ], + "id": "http://org.yourdataspace.com/credentials/2347", + "type": [ + "VerifiableCredential", + "MembershipCredential" + ], + "issuer": { + "id": "did:web:localhost%3A9876", + "additionalProperties": {} + }, + "issuanceDate": 1702339200.000000000, + "expirationDate": null, + "credentialStatus": null, + "description": null, + "name": null + } + } +} diff --git a/connector-deployment/assets/credentials/local/consumer/unsigned/dataprocessor_vc.json b/connector-deployment/assets/credentials/local/consumer/unsigned/dataprocessor_vc.json new file mode 100644 index 000000000..e65876bf7 --- /dev/null +++ b/connector-deployment/assets/credentials/local/consumer/unsigned/dataprocessor_vc.json @@ -0,0 +1,24 @@ +{ + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://w3id.org/security/suites/jws-2020/v1", + "https://www.w3.org/ns/did/v1", + { + "mvd-credentials": "https://w3id.org/mvd/credentials/", + "contractVersion": "mvd-credentials:contractVersion", + "level": "mvd-credentials:level" + } + ], + "id": "http://org.yourdataspace.com/credentials/2347", + "type": [ + "VerifiableCredential", + "DataProcessorCredential" + ], + "issuer": "did:web:localhost%3A9876", + "issuanceDate": "2023-08-18T00:00:00Z", + "credentialSubject": { + "id": "did:web:localhost%3A7083", + "contractVersion": "1.0.0", + "level": "processing" + } +} \ No newline at end of file diff --git a/connector-deployment/assets/credentials/local/consumer/unsigned/membership_vc.json b/connector-deployment/assets/credentials/local/consumer/unsigned/membership_vc.json new file mode 100644 index 000000000..65b1b56da --- /dev/null +++ b/connector-deployment/assets/credentials/local/consumer/unsigned/membership_vc.json @@ -0,0 +1,31 @@ +{ + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://w3id.org/security/suites/jws-2020/v1", + "https://www.w3.org/ns/did/v1", + { + "mvd-credentials": "https://w3id.org/mvd/credentials/", + "membership": "mvd-credentials:membership", + "membershipType": "mvd-credentials:membershipType", + "website": "mvd-credentials:website", + "contact": "mvd-credentials:contact", + "since": "mvd-credentials:since" + } + ], + "id": "http://org.yourdataspace.com/credentials/2347", + "type": [ + "VerifiableCredential", + "MembershipCredential" + ], + "issuer": "did:web:localhost%3A9876", + "issuanceDate": "2023-08-18T00:00:00Z", + "credentialSubject": { + "id": "did:web:localhost%3A7083", + "membership": { + "membershipType": "FullMember", + "website": "www.whatever.com", + "contact": "mix.max@whatever.com", + "since": "2023-01-01T00:00:00Z" + } + } +} \ No newline at end of file diff --git a/connector-deployment/assets/credentials/local/provider/dataprocessor-credential.json b/connector-deployment/assets/credentials/local/provider/dataprocessor-credential.json new file mode 100644 index 000000000..aadbef8fe --- /dev/null +++ b/connector-deployment/assets/credentials/local/provider/dataprocessor-credential.json @@ -0,0 +1,39 @@ +{ + "id": "40e24588-b510-41ca-966c-c1e0f57d1ca7", + "participantContextId": "did:web:localhost%3A7093", + "timestamp": 1700659822500, + "issuerId": "did:web:localhost%3A9876", + "holderId": "did:web:localhost%3A7093", + "state": 500, + "issuancePolicy": null, + "reissuancePolicy": null, + "verifiableCredential": { + "format": "VC1_0_JWT", + "rawVc": "eyJraWQiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYja2V5LTEiLCJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJpc3MiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYiLCJhdWQiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkZW50aXR5aHViJTNBNzA4Mzpib2IiLCJzdWIiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkZW50aXR5aHViJTNBNzA4Mzpib2IiLCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vdzNpZC5vcmcvc2VjdXJpdHkvc3VpdGVzL2p3cy0yMDIwL3YxIiwiaHR0cHM6Ly93d3cudzMub3JnL25zL2RpZC92MSIseyJtdmQtY3JlZGVudGlhbHMiOiJodHRwczovL3czaWQub3JnL212ZC9jcmVkZW50aWFscy8iLCJjb250cmFjdFZlcnNpb24iOiJtdmQtY3JlZGVudGlhbHM6Y29udHJhY3RWZXJzaW9uIiwibGV2ZWwiOiJtdmQtY3JlZGVudGlhbHM6bGV2ZWwifV0sImlkIjoiaHR0cDovL29yZy55b3VyZGF0YXNwYWNlLmNvbS9jcmVkZW50aWFscy8yMzQ3IiwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIkRhdGFQcm9jZXNzb3JDcmVkZW50aWFsIl0sImlzc3VlciI6ImRpZDp3ZWI6bG9jYWxob3N0JTNBOTg3NiIsImlzc3VhbmNlRGF0ZSI6IjIwMjMtMDgtMThUMDA6MDA6MDBaIiwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTcwOTMiLCJsZXZlbCI6InByb2Nlc3NpbmciLCJjb250cmFjdFZlcnNpb24iOiIxLjAuMCJ9fSwiaWF0IjoxNzQ4ODQ0OTE5fQ.aeb2uwwwEbaa3236XJhNOpJ_KxUIIefYeheAiw7OPtk_rXjmFOQ_aa7F09kEEgGK1NB3sijfVIEo5E96vMfZCQ", + "credential": { + "credentialSubject": [ + { + "claims": { + "id": "did:web:localhost%3A7093", + "contractVersion": "1.0.0", + "level": "processing" + } + } + ], + "id": "http://org.yourdataspace.com/credentials/1265", + "type": [ + "VerifiableCredential", + "DataProcessorCredential" + ], + "issuer": { + "id": "did:web:localhost%3A9876", + "additionalProperties": {} + }, + "issuanceDate": 1702339200.000000000, + "expirationDate": null, + "credentialStatus": null, + "description": null, + "name": null + } + } +} diff --git a/connector-deployment/assets/credentials/local/provider/membership-credential.json b/connector-deployment/assets/credentials/local/provider/membership-credential.json new file mode 100644 index 000000000..419beea63 --- /dev/null +++ b/connector-deployment/assets/credentials/local/provider/membership-credential.json @@ -0,0 +1,43 @@ +{ + "id": "40e24588-b510-41ca-966c-c1e0f57d1b14", + "participantContextId": "did:web:localhost%3A7093", + "timestamp": 1700659822500, + "issuerId": "did:web:localhost%3A9876", + "holderId": "did:web:localhost%3A7093", + "state": 500, + "issuancePolicy": null, + "reissuancePolicy": null, + "verifiableCredential": { + "rawVc": "eyJraWQiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYja2V5LTEiLCJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJpc3MiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYiLCJhdWQiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkZW50aXR5aHViJTNBNzA4Mzpib2IiLCJzdWIiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkZW50aXR5aHViJTNBNzA4Mzpib2IiLCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vdzNpZC5vcmcvc2VjdXJpdHkvc3VpdGVzL2p3cy0yMDIwL3YxIiwiaHR0cHM6Ly93d3cudzMub3JnL25zL2RpZC92MSIseyJtdmQtY3JlZGVudGlhbHMiOiJodHRwczovL3czaWQub3JnL212ZC9jcmVkZW50aWFscy8iLCJtZW1iZXJzaGlwIjoibXZkLWNyZWRlbnRpYWxzOm1lbWJlcnNoaXAiLCJtZW1iZXJzaGlwVHlwZSI6Im12ZC1jcmVkZW50aWFsczptZW1iZXJzaGlwVHlwZSIsIndlYnNpdGUiOiJtdmQtY3JlZGVudGlhbHM6d2Vic2l0ZSIsImNvbnRhY3QiOiJtdmQtY3JlZGVudGlhbHM6Y29udGFjdCIsInNpbmNlIjoibXZkLWNyZWRlbnRpYWxzOnNpbmNlIn1dLCJpZCI6Imh0dHA6Ly9vcmcueW91cmRhdGFzcGFjZS5jb20vY3JlZGVudGlhbHMvMTIzNCIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJNZW1iZXJzaGlwQ3JlZGVudGlhbCJdLCJpc3N1ZXIiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYiLCJpc3N1YW5jZURhdGUiOiIyMDIzLTA4LTE4VDAwOjAwOjAwWiIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOndlYjpsb2NhbGhvc3QlM0E3MDkzIiwibWVtYmVyc2hpcCI6eyJtZW1iZXJzaGlwVHlwZSI6IlByb3NwZWN0TWVtYmVyIiwid2Vic2l0ZSI6Ind3dy5xdWl6enF1YXp6LmNvbSIsImNvbnRhY3QiOiJmb28uYmFyQHF1aXp6cXVhenouY29tIiwic2luY2UiOiIyMDIzLTAxLTAxVDAwOjAwOjAwWiJ9fX0sImlhdCI6MTc0ODg0NDkxOX0.HmC6-GC6GalGL6n8UQ2BNDOAS1qNJ0B6A7gObM_p0psOkZqCvtSQ-gwMTX8qd5gK7eihGuAEiMQ7Z_gCvgKKAw", + "format": "VC1_0_JWT", + "credential": { + "credentialSubject": [ + { + "claims": { + "membership": { + "contact": "fizz.buzz@quizzquazz.com", + "membershipType": "PartialMember", + "since": "2023-01-01T00:00:00Z", + "website": "www.quizzquazz.com" + } + }, + "id": "did:web:localhost%3A7093" + } + ], + "id": "http://org.yourdataspace.com/credentials/1234", + "type": [ + "VerifiableCredential", + "MembershipCredential" + ], + "issuer": { + "id": "did:web:localhost%3A9876", + "additionalProperties": {} + }, + "issuanceDate": 1702339200.000000000, + "expirationDate": null, + "credentialStatus": null, + "description": null, + "name": null + } + } +} diff --git a/connector-deployment/assets/credentials/local/provider/unsigned/dataprocessor_vc.json b/connector-deployment/assets/credentials/local/provider/unsigned/dataprocessor_vc.json new file mode 100644 index 000000000..3152b5f13 --- /dev/null +++ b/connector-deployment/assets/credentials/local/provider/unsigned/dataprocessor_vc.json @@ -0,0 +1,24 @@ +{ + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://w3id.org/security/suites/jws-2020/v1", + "https://www.w3.org/ns/did/v1", + { + "mvd-credentials": "https://w3id.org/mvd/credentials/", + "contractVersion": "mvd-credentials:contractVersion", + "level": "mvd-credentials:level" + } + ], + "id": "http://org.yourdataspace.com/credentials/2347", + "type": [ + "VerifiableCredential", + "DataProcessorCredential" + ], + "issuer": "did:web:localhost%3A9876", + "issuanceDate": "2023-08-18T00:00:00Z", + "credentialSubject": { + "id": "did:web:localhost%3A7093", + "level": "processing", + "contractVersion": "1.0.0" + } +} \ No newline at end of file diff --git a/connector-deployment/assets/credentials/local/provider/unsigned/membership_vc.json b/connector-deployment/assets/credentials/local/provider/unsigned/membership_vc.json new file mode 100644 index 000000000..a2b9efe35 --- /dev/null +++ b/connector-deployment/assets/credentials/local/provider/unsigned/membership_vc.json @@ -0,0 +1,31 @@ +{ + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://w3id.org/security/suites/jws-2020/v1", + "https://www.w3.org/ns/did/v1", + { + "mvd-credentials": "https://w3id.org/mvd/credentials/", + "membership": "mvd-credentials:membership", + "membershipType": "mvd-credentials:membershipType", + "website": "mvd-credentials:website", + "contact": "mvd-credentials:contact", + "since": "mvd-credentials:since" + } + ], + "id": "http://org.yourdataspace.com/credentials/1234", + "type": [ + "VerifiableCredential", + "MembershipCredential" + ], + "issuer": "did:web:localhost%3A9876", + "issuanceDate": "2023-08-18T00:00:00Z", + "credentialSubject": { + "id": "did:web:localhost%3A7093", + "membership": { + "membershipType": "ProspectMember", + "website": "www.quizzquazz.com", + "contact": "foo.bar@quizzquazz.com", + "since": "2023-01-01T00:00:00Z" + } + } +} \ No newline at end of file diff --git a/connector-deployment/assets/env/consumer_connector.env b/connector-deployment/assets/env/consumer_connector.env new file mode 100644 index 000000000..78c803bf1 --- /dev/null +++ b/connector-deployment/assets/env/consumer_connector.env @@ -0,0 +1,38 @@ +# control plane specific config +edc.iam.issuer.id=did:web:localhost%3A7083 +web.http.port=8080 +web.http.path=/api +web.http.management.port=8081 +web.http.management.path=/api/management/ +web.http.management.auth.type=tokenbased +web.http.management.auth.key=password +web.http.protocol.port=8082 +web.http.protocol.path=/api/dsp +web.http.control.port=8083 +web.http.control.path=/api/control +web.http.catalog.port=8084 +web.http.catalog.path=/api/catalog +web.http.catalog_auth.type=tokenbased +web.http.catalog_auth.key=password +web.http.version.port=8085 +web.http.version.path=/api/version +edc.iam.did.web.use.https=false +edc.iam.sts.privatekey.alias=did:web:localhost%3A7083-alias +edc.iam.sts.publickey.id=did:web:localhost%3A7083#key-1 +edc.dsp.callback.address=http://localhost:8082/api/dsp +edc.participant.id=did:web:localhost%3A7083 +edc.catalog.cache.execution.delay.seconds=5 +edc.catalog.cache.execution.period.seconds=10 +edc.mvd.participants.list.file=deployment/assets/participants/participants.local.json +edc.management.context.enabled=true +edc.iam.sts.oauth.client.secret.alias=did:web:localhost%3A7083-sts-client-secret +edc.iam.sts.oauth.client.id=did:web:localhost%3A7083 +edc.iam.sts.oauth.token.url=http://localhost:7086/api/sts/token + +# dataplane specific config +edc.runtime.id=consumer-embedded-runtime +edc.transfer.proxy.token.verifier.publickey.alias=did:web:localhost%3A7083#key-1 +edc.transfer.proxy.token.signer.privatekey.alias=did:web:localhost%3A7083-alias +edc.dpf.selector.url=http://localhost:8083/api/control/v1/dataplanes +web.http.public.port=11001 +web.http.public.path=/api/public diff --git a/connector-deployment/assets/env/consumer_identityhub.env b/connector-deployment/assets/env/consumer_identityhub.env new file mode 100644 index 000000000..368423112 --- /dev/null +++ b/connector-deployment/assets/env/consumer_identityhub.env @@ -0,0 +1,19 @@ +web.http.port=7080 +web.http.path=/api +web.http.credentials.port=7081 +web.http.credentials.path=/api/credentials +web.http.identity.port=7082 +web.http.identity.path=/api/identity +web.http.did.port=7083 +web.http.did.path=/ +web.http.version.port=7085 +web.http.version.path=/api/version +web.http.sts.port=7086 +web.http.sts.path=/api/sts +edc.iam.did.web.use.https=false +edc.iam.sts.privatekey.alias=key-1 +edc.iam.sts.publickey.id=did:web:localhost%3A7083#key-1 +edc.ih.iam.publickey.path=./deployment/assets/consumer_public.pem +edc.ih.iam.id=did:web:localhost%3A7083 +edc.ih.api.superuser.key=c3VwZXItdXNlcg==.c3VwZXItc2VjcmV0LWtleQo= +edc.mvd.credentials.path=deployment/assets/credentials/local/consumer/ \ No newline at end of file diff --git a/connector-deployment/assets/env/issuerservice.env b/connector-deployment/assets/env/issuerservice.env new file mode 100644 index 000000000..e2aa1130d --- /dev/null +++ b/connector-deployment/assets/env/issuerservice.env @@ -0,0 +1,15 @@ +edc.issuer.statuslist.signing.key.alias=signing-key-alias +web.http.port=10010 +web.http.path=/api +web.http.sts.port=10011 +web.http.sts.path=/api/sts +web.http.issuance.port=10012 +web.http.issuance.path=/api/issuance +web.http.issueradmin.port=10013 +web.http.issueradmin.path=/api/admin +web.http.version.port=10014 +web.http.version.path=/.well-known/api +web.http.identity.port=10015 +web.http.identity.path=/api/identity +edc.iam.did.web.use.https=false +edc.ih.api.superuser.key=c3VwZXItdXNlcg==.c3VwZXItc2VjcmV0LWtleQo= \ No newline at end of file diff --git a/connector-deployment/assets/env/provider_catalogserver.env b/connector-deployment/assets/env/provider_catalogserver.env new file mode 100644 index 000000000..7b9706ee6 --- /dev/null +++ b/connector-deployment/assets/env/provider_catalogserver.env @@ -0,0 +1,20 @@ +edc.iam.issuer.id=did:web:localhost%3A7093 +web.http.port=8090 +web.http.path=/api +web.http.management.port=8091 +web.http.management.path=/api/management +web.http.management.auth.type=tokenbased +web.http.management.auth.key=password +web.http.protocol.port=8092 +web.http.protocol.path=/api/dsp +web.http.control.port=8093 +web.http.control.path=/api/control +edc.iam.did.web.use.https=false +edc.iam.sts.privatekey.alias=did:web:localhost%3A7093-alias +edc.iam.sts.publickey.id=did:web:localhost%3A7093#key-1 +edc.dsp.callback.address=http://localhost:8092/api/dsp +edc.participant.id=did:web:localhost%3A7093 +edc.management.context.enabled=true +edc.iam.sts.oauth.client.secret.alias=did:web:localhost%3A7093-sts-client-secret +edc.iam.sts.oauth.client.id=did:web:localhost%3A7093 +edc.iam.sts.oauth.token.url=http://localhost:7096/api/sts/token \ No newline at end of file diff --git a/connector-deployment/assets/env/provider_connector_manufacturing.env b/connector-deployment/assets/env/provider_connector_manufacturing.env new file mode 100644 index 000000000..e041c8fb0 --- /dev/null +++ b/connector-deployment/assets/env/provider_connector_manufacturing.env @@ -0,0 +1,38 @@ +# control plane specific config +edc.iam.issuer.id=did:web:localhost%3A7093 +web.http.port=8290 +web.http.path=/api +web.http.management.port=8291 +web.http.management.path=/api/management/ +web.http.management.auth.type=tokenbased +web.http.management.auth.key=password +web.http.protocol.port=8292 +web.http.protocol.path=/api/dsp +web.http.control.port=8293 +web.http.control.path=/api/control +web.http.catalog.port=8294 +web.http.catalog.path=/api/catalog +web.http.catalog_auth.type=tokenbased +web.http.catalog_auth.key=password +web.http.version.port=8295 +web.http.version.path=/api/version +edc.iam.did.web.use.https=false +edc.iam.sts.privatekey.alias=did:web:localhost%3A7093-alias +edc.iam.sts.publickey.id=did:web:localhost%3A7093#key-1 +edc.dsp.callback.address=http://localhost:8292/api/dsp +edc.participant.id=did:web:localhost%3A7093 +edc.catalog.cache.execution.delay.seconds=5 +edc.catalog.cache.execution.period.seconds=10 +edc.mvd.participants.list.file=deployment/assets/participants/participants.local.json +edc.management.context.enabled=true +edc.iam.sts.oauth.client.secret.alias=did:web:localhost%3A7093-sts-client-secret +edc.iam.sts.oauth.client.id=did:web:localhost%3A7093 +edc.iam.sts.oauth.token.url=http://localhost:7096/api/sts/token + +# dataplane specific config +edc.runtime.id=provider-manufacturing-embedded-runtime +edc.transfer.proxy.token.verifier.publickey.alias=did:web:localhost%3A7093#key-1 +edc.transfer.proxy.token.signer.privatekey.alias=did:web:localhost%3A7093-alias +edc.dpf.selector.url=http://localhost:8293/api/control/v1/dataplanes +web.http.public.port=12002 +web.http.public.path=/api/public diff --git a/connector-deployment/assets/env/provider_connector_qna.env b/connector-deployment/assets/env/provider_connector_qna.env new file mode 100644 index 000000000..353585982 --- /dev/null +++ b/connector-deployment/assets/env/provider_connector_qna.env @@ -0,0 +1,38 @@ +# control plane specific config +edc.iam.issuer.id=did:web:localhost%3A7093 +web.http.port=8190 +web.http.path=/api +web.http.management.port=8191 +web.http.management.path=/api/management/ +web.http.management.auth.type=tokenbased +web.http.management.auth.key=password +web.http.protocol.port=8192 +web.http.protocol.path=/api/dsp +web.http.control.port=8193 +web.http.control.path=/api/control +web.http.catalog.port=8194 +web.http.catalog.path=/api/catalog +web.http.catalog_auth.type=tokenbased +web.http.catalog_auth.key=password +web.http.version.port=8195 +web.http.version.path=/api/version +edc.iam.did.web.use.https=false +edc.iam.sts.privatekey.alias=did:web:localhost%3A7093-alias +edc.iam.sts.publickey.id=did:web:localhost%3A7093#key-1 +edc.dsp.callback.address=http://localhost:8192/api/dsp +edc.participant.id=did:web:localhost%3A7093 +edc.catalog.cache.execution.delay.seconds=5 +edc.catalog.cache.execution.period.seconds=10 +edc.mvd.participants.list.file=deployment/assets/participants/participants.local.json +edc.management.context.enabled=true +edc.iam.sts.oauth.client.secret.alias=did:web:localhost%3A7093-sts-client-secret +edc.iam.sts.oauth.client.id=did:web:localhost%3A7093 +edc.iam.sts.oauth.token.url=http://localhost:7096/api/sts/token + +# dataplane specific config +edc.runtime.id=provider-qna-embedded-runtime +edc.transfer.proxy.token.verifier.publickey.alias=did:web:localhost%3A7093#key-1 +edc.transfer.proxy.token.signer.privatekey.alias=did:web:localhost%3A7093-alias +edc.dpf.selector.url=http://localhost:8193/api/control/v1/dataplanes +web.http.public.port=12001 +web.http.public.path=/api/public diff --git a/connector-deployment/assets/env/provider_identityhub.env b/connector-deployment/assets/env/provider_identityhub.env new file mode 100644 index 000000000..7f2febbe9 --- /dev/null +++ b/connector-deployment/assets/env/provider_identityhub.env @@ -0,0 +1,19 @@ +web.http.port=7090 +web.http.path=/api +web.http.credentials.port=7091 +web.http.credentials.path=/api/credentials/ +web.http.identity.port=7092 +web.http.identity.path=/api/identity +web.http.did.port=7093 +web.http.did.path=/ +web.http.version.port=7095 +web.http.version.path=/api/version +web.http.sts.port=7096 +web.http.sts.path=/api/sts +edc.iam.did.web.use.https=false +edc.iam.sts.privatekey.alias=key-1 +edc.iam.sts.publickey.id=did:web:localhost%3A7093#key-1 +edc.ih.iam.publickey.path=./deployment/assets/provider_public.pem +edc.ih.iam.id=did:web:localhost%3A7093 +edc.ih.api.superuser.key=c3VwZXItdXNlcg==.c3VwZXItc2VjcmV0LWtleQo= +edc.mvd.credentials.path=deployment/assets/credentials/local/provider/ \ No newline at end of file diff --git a/connector-deployment/assets/issuer/did.docker.json b/connector-deployment/assets/issuer/did.docker.json new file mode 100644 index 000000000..1c819d142 --- /dev/null +++ b/connector-deployment/assets/issuer/did.docker.json @@ -0,0 +1,26 @@ +{ + "service": [], + "verificationMethod": [ + { + "id": "did:web:localhost%3A9876#key-1", + "type": "JsonWebKey2020", + "controller": "did:web:localhost%3A9876", + "publicKeyMultibase": null, + "publicKeyJwk": { + "kty": "OKP", + "crv": "Ed25519", + "x": "Hsq2QXPbbsU7j6JwXstbpxGSgliI04g_fU3z2nwkuVc" + } + } + ], + "authentication": [ + "key-1" + ], + "id": "did:web:localhost%3A9876", + "@context": [ + "https://www.w3.org/ns/did/v1", + { + "@base": "did:web:localhost%3A9876" + } + ] +} \ No newline at end of file diff --git a/connector-deployment/assets/issuer/did.k8s.json b/connector-deployment/assets/issuer/did.k8s.json new file mode 100644 index 000000000..b6b0d01dc --- /dev/null +++ b/connector-deployment/assets/issuer/did.k8s.json @@ -0,0 +1,26 @@ +{ + "service": [], + "verificationMethod": [ + { + "id": "did:web:dataspace-issuer#key-1", + "type": "JsonWebKey2020", + "controller": "did:web:dataspace-issuer", + "publicKeyMultibase": null, + "publicKeyJwk": { + "kty": "OKP", + "crv": "Ed25519", + "x": "Hsq2QXPbbsU7j6JwXstbpxGSgliI04g_fU3z2nwkuVc" + } + } + ], + "authentication": [ + "key-1" + ], + "id": "did:web:dataspace-issuer", + "@context": [ + "https://www.w3.org/ns/did/v1", + { + "@base": "did:web:dataspace-issuer" + } + ] +} \ No newline at end of file diff --git a/connector-deployment/assets/issuer/nginx.conf b/connector-deployment/assets/issuer/nginx.conf new file mode 100644 index 000000000..fa45fbed2 --- /dev/null +++ b/connector-deployment/assets/issuer/nginx.conf @@ -0,0 +1,9 @@ +events { worker_connections 1024; } + +http { + server { + listen 80; + root /var/www/; + index index.html; + } + } \ No newline at end of file diff --git a/connector-deployment/assets/issuer_private.pem b/connector-deployment/assets/issuer_private.pem new file mode 100644 index 000000000..8a63542f7 --- /dev/null +++ b/connector-deployment/assets/issuer_private.pem @@ -0,0 +1,3 @@ +-----BEGIN PRIVATE KEY----- +MC4CAQAwBQYDK2VwBCIEID1gMsekH7JN9Q/L2UMCBkAPET10NE0T2BB4c2rRSBzg +-----END PRIVATE KEY----- diff --git a/connector-deployment/assets/issuer_public.pem b/connector-deployment/assets/issuer_public.pem new file mode 100644 index 000000000..51b250241 --- /dev/null +++ b/connector-deployment/assets/issuer_public.pem @@ -0,0 +1,3 @@ +-----BEGIN PUBLIC KEY----- +MCowBQYDK2VwAyEAHsq2QXPbbsU7j6JwXstbpxGSgliI04g/fU3z2nwkuVc= +-----END PUBLIC KEY----- diff --git a/connector-deployment/assets/participants/participants.k8s.json b/connector-deployment/assets/participants/participants.k8s.json new file mode 100644 index 000000000..993eeacee --- /dev/null +++ b/connector-deployment/assets/participants/participants.k8s.json @@ -0,0 +1,4 @@ +{ + "consumer-corp": "did:web:consumer-identityhub%3A7083:consumer", + "provider-corp": "did:web:provider-identityhub%3A7083:provider" +} \ No newline at end of file diff --git a/connector-deployment/assets/participants/participants.local.json b/connector-deployment/assets/participants/participants.local.json new file mode 100644 index 000000000..ae3849cf4 --- /dev/null +++ b/connector-deployment/assets/participants/participants.local.json @@ -0,0 +1,4 @@ +{ + "consumer-corp": "did:web:localhost%3A7083", + "provider-corp": "did:web:localhost%3A7093" +} \ No newline at end of file diff --git a/connector-deployment/assets/provider_private.pem b/connector-deployment/assets/provider_private.pem new file mode 100644 index 000000000..81c28bac2 --- /dev/null +++ b/connector-deployment/assets/provider_private.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIARDUGJgKy1yzxkueIJ1k3MPUWQ/tbQWQNqW6TjyHpdcoAoGCCqGSM49 +AwEHoUQDQgAE1l0Lof0a1yBc8KXhesAnoBvxZw5roYnkAXuqCYfNK3ex+hMWFuiX +GUxHlzShAehR6wvwzV23bbC0tcFcVgW//A== +-----END EC PRIVATE KEY----- \ No newline at end of file diff --git a/connector-deployment/assets/provider_public.pem b/connector-deployment/assets/provider_public.pem new file mode 100644 index 000000000..977a19576 --- /dev/null +++ b/connector-deployment/assets/provider_public.pem @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1l0Lof0a1yBc8KXhesAnoBvxZw5r +oYnkAXuqCYfNK3ex+hMWFuiXGUxHlzShAehR6wvwzV23bbC0tcFcVgW//A== +-----END PUBLIC KEY----- \ No newline at end of file diff --git a/connector-deployment/connector.tf b/connector-deployment/connector.tf new file mode 100644 index 000000000..26c1acdd2 --- /dev/null +++ b/connector-deployment/connector.tf @@ -0,0 +1,86 @@ +# +# Copyright (c) 2024 Metaform Systems, Inc. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License, Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# +# Contributors: +# Metaform Systems, Inc. - initial API and implementation +# + +# This file deploys all the components needed for the consumer side of the scenario, +# i.e. the connector, an identityhub and a vault. + +# +resource "kubernetes_namespace_v1" "ns_participant" { + metadata { + name = var.participant + } +} + +# connector +module "participant-connector" { + source = "./modules/connector" + humanReadableName = var.participant + participantId = local.participant-did + controlplane_image = var.controlplane_image + dataplane_image = var.dataplane_image + database = { + user = var.participant + password = random_password.participant_password.result + url = local.database_url + } + vault-url = local.vault_url + namespace = kubernetes_namespace_v1.ns_participant.metadata.0.name + sts-token-url = "${module.participant-identityhub.sts-token-url}/token" + useSVE = var.useSVE + s3_endpoint = "https://${module.assets_s3_bucket.bucket_name}.s3.eu-west-1.amazonaws.com" + # aws_access_key = aws_iam_access_key.deployer.id + # aws_secret_key = aws_iam_access_key.deployer.secret + service_account_role_arn = module.participant-s3-role.role_arn + management_auth_key = var.participant_management_auth_key +} + +# consumer identity hub +module "participant-identityhub" { + depends_on = [module.participant-vault] + source = "./modules/identity-hub" + credentials-dir = "./assets/credentials/k8s/${var.participant}" + humanReadableName = "${var.participant}-identityhub" + participantId = local.participant-did + vault-url = local.vault_url + service-name = var.participant + identityhub_image = var.identityhub_image + identity_auth_key = var.participant_management_auth_key + database = { + user = var.participant + password = random_password.participant_password.result + url = local.database_url + } + namespace = kubernetes_namespace_v1.ns_participant.metadata.0.name + useSVE = var.useSVE +} + +# participant vault +module "participant-vault" { + source = "./modules/vault" + humanReadableName = "${var.participant}-vault" + namespace = kubernetes_namespace_v1.ns_participant.metadata.0.name +} + +# Seed Vault with participant private key from assets/_private.pem (produced by produce_participant_credentials.sh) +resource "null_resource" "seed_vault_participant_key" { + count = fileexists("${path.module}/assets/${var.participant}_private.pem") ? 1 : 0 + depends_on = [module.participant-vault] + triggers = { + participant = var.participant + pem = fileexists("${path.module}/assets/${var.participant}_private.pem") ? filemd5("${path.module}/assets/${var.participant}_private.pem") : "no-file" + } + provisioner "local-exec" { + command = "chmod +x scripts/seed_vault_participant_key.sh && ./scripts/seed_vault_participant_key.sh ${var.participant}" + working_dir = path.module + } +} diff --git a/connector-deployment/data.tf b/connector-deployment/data.tf new file mode 100644 index 000000000..b24bc49d6 --- /dev/null +++ b/connector-deployment/data.tf @@ -0,0 +1,11 @@ +# Current AWS account +data "aws_caller_identity" "current" {} + +# EKS data +data "aws_eks_cluster" "eks" { + name = "${var.project}-${var.environment}-eks" +} + +data "aws_iam_openid_connect_provider" "eks_oidc" { + url = data.aws_eks_cluster.eks.identity[0].oidc[0].issuer +} \ No newline at end of file diff --git a/connector-deployment/database.tf b/connector-deployment/database.tf new file mode 100644 index 000000000..8ee319c1d --- /dev/null +++ b/connector-deployment/database.tf @@ -0,0 +1,46 @@ +resource "random_password" "participant_password" { + length = 16 + special = true + override_special = "!#$%&()-_=+[]{}<>?" +} + +provider "postgresql" { + host = var.postgres_endpoint + port = var.postgres_port + database = "participants" + username = "dbadmin" + password = var.postgres_admin_password + sslmode = "require" + connect_timeout = 15 + superuser = false +} + +resource "postgresql_role" "participant_user" { + name = var.participant + login = true + password = random_password.participant_password.result +} + +resource "postgresql_database" "participant_database" { + name = var.participant + owner = postgresql_role.participant_user.name + lc_collate = "en_US.UTF-8" + lc_ctype = "en_US.UTF-8" + template = "template0" + allow_connections = true +} + +resource "postgresql_grant" "db_privs" { + database = postgresql_database.participant_database.name + role = postgresql_role.participant_user.name + object_type = "database" + privileges = ["CONNECT", "CREATE", "TEMPORARY"] +} + +resource "postgresql_grant" "schema_privs" { + database = postgresql_database.participant_database.name + role = postgresql_role.participant_user.name + schema = "public" + object_type = "schema" + privileges = ["CREATE", "USAGE"] +} diff --git a/connector-deployment/iam.tf b/connector-deployment/iam.tf new file mode 100644 index 000000000..f521e4a44 --- /dev/null +++ b/connector-deployment/iam.tf @@ -0,0 +1,15 @@ +# resource "aws_iam_user" "main" { +# name = "${var.project}-${var.participant}-s3-user" + +# # tags = merge(var.tags, { +# # Name = "${var.tenant}-${var.project}-${var.environment}-${var.role}-user" +# # tenant = var.tenant +# # Proyecto = length(var.project) == 3 ? upper(var.project) : title(var.project) +# # Entorno = title(var.environment) +# # Rol = var.role +# # }) +# } + +# resource "aws_iam_access_key" "deployer" { +# user = aws_iam_user.main.name +# } \ No newline at end of file diff --git a/connector-deployment/kms.tf b/connector-deployment/kms.tf new file mode 100644 index 000000000..5cd3b25f1 --- /dev/null +++ b/connector-deployment/kms.tf @@ -0,0 +1,7 @@ +module "kms" { + source = "./modules/kms" + environment = var.environment + project = var.project + alias = "${var.participant}-key" + role = "kms" +} \ No newline at end of file diff --git a/connector-deployment/locals.tf b/connector-deployment/locals.tf new file mode 100644 index 000000000..34ed7fa01 --- /dev/null +++ b/connector-deployment/locals.tf @@ -0,0 +1,13 @@ +locals { + participant-did = "did:web:${var.participant}-identityhub.${var.participant}%3A7083:${var.participant}" + database_url = "jdbc:postgresql://${var.postgres_endpoint}:${var.postgres_port}/${var.participant}" + vault_url = "http://${var.participant}-vault:8200" + + # S3 replication: only enabled for participants that replicate to another account + replication_enabled = var.replicate_to_participant && var.participant_account_id != "" && var.participant_bucket_name != "" + + eks_oidc = trimprefix( + data.aws_eks_cluster.eks.identity[0].oidc[0].issuer, + "https://" + ) +} diff --git a/connector-deployment/modules/connector/controlplane.tf b/connector-deployment/modules/connector/controlplane.tf new file mode 100644 index 000000000..6cbc26316 --- /dev/null +++ b/connector-deployment/modules/connector/controlplane.tf @@ -0,0 +1,213 @@ +# +# Copyright (c) 2023 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 +# + +resource "kubernetes_deployment" "controlplane" { + metadata { + name = "${lower(var.humanReadableName)}-controlplane" + namespace = var.namespace + labels = { + App = "${lower(var.humanReadableName)}-controlplane" + } + } + + spec { + replicas = 1 + selector { + match_labels = { + App = "${lower(var.humanReadableName)}-controlplane" + } + } + + template { + metadata { + labels = { + App = "${lower(var.humanReadableName)}-controlplane" + } + } + + spec { + service_account_name = kubernetes_service_account.s3_sa.metadata[0].name + container { + name = "connector-${lower(var.humanReadableName)}" + image = var.controlplane_image + image_pull_policy = "IfNotPresent" + + env_from { + config_map_ref { + name = kubernetes_config_map.connector-config.metadata[0].name + } + } + + port { + container_port = var.ports.management + name = "management-port" + } + port { + container_port = var.ports.web + name = "default-port" + } + port { + container_port = var.ports.debug + name = "debug-port" + } + port { + container_port = var.ports.control + name = "control-port" + } + port { + container_port = var.ports.catalog + name = "catalog-port" + } + port { + container_port = var.ports.protocol + name = "protocol-port" + } + + liveness_probe { + http_get { + path = "/api/check/liveness" + port = var.ports.web + } + failure_threshold = 10 + period_seconds = 5 + timeout_seconds = 30 + } + + readiness_probe { + http_get { + path = "/api/check/readiness" + port = var.ports.web + } + failure_threshold = 10 + period_seconds = 5 + timeout_seconds = 30 + } + + startup_probe { + http_get { + path = "/api/check/startup" + port = var.ports.web + } + failure_threshold = 10 + period_seconds = 5 + timeout_seconds = 30 + } + + volume_mount { + mount_path = "/etc/registry" + name = "registry-volume" + } + + volume_mount { + mount_path = "/etc/participants" + name = "participants-volume" + } + } + + volume { + name = "registry-volume" + config_map { + name = kubernetes_config_map.connector-config.metadata[0].name + } + } + + volume { + name = "participants-volume" + config_map { + name = kubernetes_config_map.participants-map.metadata[0].name + } + } + } + } + } +} + +resource "kubernetes_config_map" "participants-map" { + metadata { + name = "${var.humanReadableName}-participants" + namespace = var.namespace + } + + data = { + "participants.json" = file(var.participant-list-file) + } + +} + +resource "kubernetes_config_map" "connector-config" { + metadata { + name = "${lower(var.humanReadableName)}-controlplane-config" + namespace = var.namespace + } + + ## Create databases for keycloak and MIW, create users and assign privileges + data = { + EDC_PARTICIPANT_ID = var.participantId + EDC_IAM_ISSUER_ID = var.participantId + EDC_IAM_DID_WEB_USE_HTTPS = false + WEB_HTTP_PORT = var.ports.web + WEB_HTTP_PATH = "/api" + WEB_HTTP_MANAGEMENT_PORT = var.ports.management + WEB_HTTP_MANAGEMENT_PATH = "/api/management" + WEB_HTTP_MANAGEMENT_AUTH_TYPE = "tokenbased" + WEB_HTTP_MANAGEMENT_AUTH_KEY = var.management_auth_key + WEB_HTTP_CONTROL_PORT = var.ports.control + WEB_HTTP_CONTROL_PATH = "/api/control" + WEB_HTTP_PROTOCOL_PORT = var.ports.protocol + WEB_HTTP_PROTOCOL_PATH = "/api/dsp" + WEB_HTTP_CATALOG_PORT = var.ports.catalog + WEB_HTTP_CATALOG_PATH = "/api/catalog" + WEB_HTTP_CATALOG_AUTH_TYPE = "tokenbased" + WEB_HTTP_CATALOG_AUTH_KEY = var.management_auth_key + # Namespace-qualified so other participants (e.g. provider) can resolve when sending agreement/termination + EDC_DSP_CALLBACK_ADDRESS = "http://${local.controlplane-service-name}.${var.namespace}:${var.ports.protocol}/api/dsp" + EDC_IAM_STS_PRIVATEKEY_ALIAS = "${var.participantId}#${var.aliases.sts-private-key}" + EDC_IAM_STS_PUBLICKEY_ID = "${var.participantId}#${var.aliases.sts-public-key-id}" + JAVA_TOOL_OPTIONS = "${var.useSVE ? "-XX:UseSVE=0 " : ""}-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=${var.ports.debug}" + EDC_IH_AUDIENCE_REGISTRY_PATH = "/etc/registry/registry.json" + EDC_VAULT_HASHICORP_URL = var.vault-url + EDC_VAULT_HASHICORP_TOKEN = var.vault-token + EDC_MVD_PARTICIPANTS_LIST_FILE = "/etc/participants/participants.json" + EDC_CATALOG_CACHE_EXECUTION_DELAY_SECONDS = 10 + EDC_CATALOG_CACHE_EXECUTION_PERIOD_SECONDS = 10 + EDC_DATASOURCE_DEFAULT_URL = var.database.url + EDC_DATASOURCE_DEFAULT_USER = var.database.user + EDC_DATASOURCE_DEFAULT_PASSWORD = var.database.password + EDC_SQL_SCHEMA_AUTOCREATE = true + + # remote STS configuration + EDC_IAM_STS_OAUTH_TOKEN_URL = var.sts-token-url + EDC_IAM_STS_OAUTH_CLIENT_ID = var.participantId + EDC_IAM_STS_OAUTH_CLIENT_SECRET_ALIAS = local.sts_client_secret_alias + + # S3 configuration for AmazonS3 DataAddress support + # These variables enable the ControlPlane to validate and accept AmazonS3 DataAddress types + # Default values are for LocalStack (can be overridden by setting these values in the ConfigMap manually) + EDC_S3_ENDPOINT = var.s3_endpoint + # AWS_ACCESS_KEY_ID = var.aws_access_key + # AWS_SECRET_ACCESS_KEY = var.aws_secret_key + AWS_REGION = "eu-west-1" + AWS_REGION = "eu-west-1" + + # Remove participant creation - participants are controlled elsewhere + # Note: EDC_RUNTIME_DISABLED_EXTENSIONS may not prevent initialization if extension + # is in the Docker image classpath. Providing config value as fallback. + EDC_MVD_PARTICIPANTS_LIST_FILE = "/dev/null" + } +} diff --git a/connector-deployment/modules/connector/dataplane.tf b/connector-deployment/modules/connector/dataplane.tf new file mode 100644 index 000000000..78fe8ac3d --- /dev/null +++ b/connector-deployment/modules/connector/dataplane.tf @@ -0,0 +1,149 @@ +# +# Copyright (c) 2023 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 +# + +resource "kubernetes_deployment" "dataplane" { + # needs a hard dependency, otherwise the dataplane registration fails, and it is not retried + depends_on = [kubernetes_deployment.controlplane] + metadata { + name = "${lower(var.humanReadableName)}-dataplane" + namespace = var.namespace + labels = { + App = "${lower(var.humanReadableName)}-dataplane" + } + } + + spec { + replicas = 1 + selector { + match_labels = { + App = "${lower(var.humanReadableName)}-dataplane" + } + } + + template { + metadata { + labels = { + App = "${lower(var.humanReadableName)}-dataplane" + } + } + + spec { + service_account_name = kubernetes_service_account.s3_sa.metadata[0].name + container { + name = "dataplane-${lower(var.humanReadableName)}" + image = var.dataplane_image + image_pull_policy = "IfNotPresent" + + env_from { + config_map_ref { + name = kubernetes_config_map.dataplane-config.metadata[0].name + } + } + + port { + container_port = var.ports.public + name = "public-port" + } + + port { + container_port = var.ports.debug + name = "debug-port" + } + + liveness_probe { + http_get { + path = "/api/check/liveness" + port = var.ports.web + } + failure_threshold = 10 + period_seconds = 5 + timeout_seconds = 30 + } + + readiness_probe { + http_get { + path = "/api/check/readiness" + port = var.ports.web + } + failure_threshold = 10 + period_seconds = 5 + timeout_seconds = 30 + } + + startup_probe { + http_get { + path = "/api/check/startup" + port = var.ports.web + } + failure_threshold = 10 + period_seconds = 5 + timeout_seconds = 30 + } + } + } + } + } +} + +resource "kubernetes_config_map" "dataplane-config" { + metadata { + name = "${lower(var.humanReadableName)}-dataplane-config" + namespace = var.namespace + } + + ## Create databases for keycloak and MIW, create users and assign privileges + data = { + # hostname is "localhost" by default, but must be the service name at which the dataplane is reachable. URL scheme and port are appended by the application + EDC_HOSTNAME = local.dataplane-service-name + EDC_RUNTIME_ID = "${var.humanReadableName}-dataplane" + EDC_PARTICIPANT_ID = var.participantId + EDC_TRANSFER_PROXY_TOKEN_VERIFIER_PUBLICKEY_ALIAS = "${var.participantId}#${var.aliases.sts-public-key-id}" + EDC_TRANSFER_PROXY_TOKEN_SIGNER_PRIVATEKEY_ALIAS = "${var.participantId}#${var.aliases.sts-private-key}" + EDC_DPF_SELECTOR_URL = "http://${local.controlplane-service-name}:${var.ports.control}/api/control/v1/dataplanes" + WEB_HTTP_PORT = var.ports.web + WEB_HTTP_PATH = "/api" + WEB_HTTP_CONTROL_PORT = var.ports.control + WEB_HTTP_CONTROL_PATH = "/api/control" + WEB_HTTP_PUBLIC_PORT = var.ports.public + WEB_HTTP_PUBLIC_PATH = "/api/public" + EDC_VAULT_HASHICORP_URL = var.vault-url + EDC_VAULT_HASHICORP_TOKEN = var.vault-token + JAVA_TOOL_OPTIONS = "${var.useSVE ? "-XX:UseSVE=0 " : ""}-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=${var.ports.debug}" + EDC_DATASOURCE_DEFAULT_URL = var.database.url + EDC_DATASOURCE_DEFAULT_USER = var.database.user + EDC_DATASOURCE_DEFAULT_PASSWORD = var.database.password + EDC_SQL_SCHEMA_AUTOCREATE = true + + # remote STS configuration + EDC_IAM_STS_OAUTH_TOKEN_URL = var.sts-token-url + EDC_IAM_STS_OAUTH_CLIENT_ID = var.participantId + EDC_IAM_STS_OAUTH_CLIENT_SECRET_ALIAS = local.sts_client_secret_alias + + # Remove participant creation - participants are controlled elsewhere + # Note: EDC_RUNTIME_DISABLED_EXTENSIONS may not prevent initialization if extension + # is in the Docker image classpath. Providing config value as fallback. + EDC_MVD_PARTICIPANTS_LIST_FILE = "/dev/null" + + EDC_S3_ENDPOINT = var.s3_endpoint + # AWS_ACCESS_KEY_ID = var.aws_access_key + # AWS_SECRET_ACCESS_KEY = var.aws_secret_key + AWS_REGION = "eu-west-1" + AWS_DEFAULT_REGION = "eu-west-1" + } +} diff --git a/connector-deployment/modules/connector/ingress.tf b/connector-deployment/modules/connector/ingress.tf new file mode 100644 index 000000000..8c4b5d3af --- /dev/null +++ b/connector-deployment/modules/connector/ingress.tf @@ -0,0 +1,99 @@ +# +# Copyright (c) 2023 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 +# + +resource "kubernetes_ingress_v1" "api-ingress" { + metadata { + name = "${var.humanReadableName}-ingress" + namespace = var.namespace + annotations = { + "nginx.ingress.kubernetes.io/rewrite-target" = "/$2" + "nginx.ingress.kubernetes.io/use-regex" = "true" + } + } + spec { + ingress_class_name = "nginx" + rule { + http { + path { + path = "/${var.humanReadableName}/health(/|$)(.*)" + backend { + service { + name = kubernetes_service.controlplane-service.metadata.0.name + port { + number = var.ports.web + } + } + } + } + + path { + path = "/${var.humanReadableName}/cp(/|$)(.*)" + backend { + service { + name = kubernetes_service.controlplane-service.metadata.0.name + port { + number = var.ports.management + } + } + } + } + + path { + path = "/${var.humanReadableName}/public(/|$)(.*)" + backend { + service { + name = kubernetes_service.dataplane-service.metadata.0.name + port { + number = var.ports.public + } + } + } + } + + path { + path = "/${var.humanReadableName}/fc(/|$)(.*)" + backend { + service { + name = kubernetes_service.controlplane-service.metadata.0.name + port { + number = var.ports.catalog + } + } + } + } + + path { + path = "/${var.humanReadableName}/vault(/|$)(.*)" + backend { + service { + name = "${var.humanReadableName}-vault" + port { + number = 8200 + } + } + } + } + } + } + } +} + +locals { + data-plane-service = "${var.humanReadableName}-dataplane" +} diff --git a/deployment/kind.config.yaml b/connector-deployment/modules/connector/outputs.tf similarity index 58% rename from deployment/kind.config.yaml rename to connector-deployment/modules/connector/outputs.tf index 9d918bb2d..81a5e9c54 100644 --- a/deployment/kind.config.yaml +++ b/connector-deployment/modules/connector/outputs.tf @@ -1,5 +1,5 @@ # -# Copyright (c) 2023 Bayerische Motoren Werke Aktiengesellschaft +# Copyright (c) 2023 Contributors to the Eclipse Foundation # # See the NOTICE file(s) distributed with this work for additional # information regarding copyright ownership. @@ -17,21 +17,22 @@ # SPDX-License-Identifier: Apache-2.0 # ---- -kind: Cluster -apiVersion: kind.x-k8s.io/v1alpha4 -nodes: - - role: control-plane - kubeadmConfigPatches: - - | - kind: InitConfiguration - nodeRegistration: - kubeletExtraArgs: - node-labels: "ingress-ready=true" - extraPortMappings: - - containerPort: 80 - hostPort: 80 - protocol: TCP - - containerPort: 443 - hostPort: 443 - protocol: TCP \ No newline at end of file +output "connector-node-ip" { + value = kubernetes_service.controlplane-service.spec.0.cluster_ip +} + + +output "database-name" { + value = var.database +} + +output "ports" { + value = var.ports +} + +output "audience-mapping" { + value = { + # dspAudience = "http://${local.connector-cluster-ip}:${var.ports.protocol}/api/dsp" + dcpAudience = var.participantId + } +} diff --git a/connector-deployment/modules/connector/serviceaccount.tf b/connector-deployment/modules/connector/serviceaccount.tf new file mode 100644 index 000000000..fc92cb7a5 --- /dev/null +++ b/connector-deployment/modules/connector/serviceaccount.tf @@ -0,0 +1,10 @@ +resource "kubernetes_service_account" "s3_sa" { + metadata { + name = "${lower(var.humanReadableName)}-s3-sa" + namespace = var.namespace + + annotations = { + "eks.amazonaws.com/role-arn" = var.service_account_role_arn + } + } +} \ No newline at end of file diff --git a/connector-deployment/modules/connector/services.tf b/connector-deployment/modules/connector/services.tf new file mode 100644 index 000000000..7299ca7d2 --- /dev/null +++ b/connector-deployment/modules/connector/services.tf @@ -0,0 +1,98 @@ +# +# Copyright (c) 2023 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 +# + +resource "kubernetes_service" "controlplane-service" { + metadata { + name = local.controlplane-service-name + namespace = var.namespace + } + spec { + type = "NodePort" + selector = { + App = kubernetes_deployment.controlplane.spec.0.template.0.metadata[0].labels.App + } + port { + name = "health" + port = var.ports.web + } + port { + name = "management" + port = var.ports.management + } + port { + name = "catalog" + port = var.ports.catalog + } + port { + name = "protocol" + port = var.ports.protocol + } + port { + name = "debug" + port = var.ports.debug + } + port { + name = "control" + port = var.ports.control + } + } +} + +resource "kubernetes_service" "dataplane-service" { + metadata { + name = local.dataplane-service-name + namespace = var.namespace + } + spec { + type = "NodePort" + selector = { + App = kubernetes_deployment.dataplane.spec.0.template.0.metadata[0].labels.App + } + port { + name = "control" + port = var.ports.control + } + port { + name = "public" + port = var.ports.public + } + } +} + +resource "kubernetes_service" "dataspace-issuer" { + metadata { + name = "dataspace-issuer" + namespace = var.namespace + } + spec { + type = "ExternalName" + external_name = "dataspace-issuer.kordat.svc.cluster.local" + } +} + +resource "kubernetes_service" "dataspace-issuer-service" { + metadata { + name = "dataspace-issuer-service" + namespace = var.namespace + } + spec { + type = "ExternalName" + external_name = "dataspace-issuer-service.kordat.svc.cluster.local" + } +} diff --git a/connector-deployment/modules/connector/variables.tf b/connector-deployment/modules/connector/variables.tf new file mode 100644 index 000000000..764278fcf --- /dev/null +++ b/connector-deployment/modules/connector/variables.tf @@ -0,0 +1,153 @@ +# +# Copyright (c) 2023 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 +# + +## Normally, you shouldn't need to change any values here. If you do, please be sure to also change them in the seed script (seed-k8s.sh). +## Neglecting to do that will render the connectors and identity hubs inoperable! + + +variable "image-pull-policy" { + default = "Always" + type = string + description = "Kubernetes ImagePullPolicy for all images" +} + +variable "humanReadableName" { + type = string + description = "Human readable name of the connector, NOT the BPN!!. Required." +} + +variable "participantId" { + type = string + description = "DID:WEB identifier of the participant, will be used as runtime participantId" +} + +variable "namespace" { + type = string +} + +variable "ports" { + type = object({ + web = number + management = number + protocol = number + control = number + catalog = number + debug = number + public = number + }) + default = { + web = 8080 + management = 8081 + protocol = 8082 + control = 8083 + catalog = 8084 + debug = 1044 + public = 11002 + } +} + +variable "database" { + type = object({ + url = string + user = string + password = string + }) +} + +variable "participant-list-file" { + type = string + default = "./assets/participants/participants.k8s.json" +} + +variable "vault-token" { + default = "root" + description = "This is the authentication token for the vault. DO NOT USE THIS IN PRODUCTION!" + type = string +} + +variable "vault-url" { + description = "URL of the Hashicorp Vault" + type = string +} + +variable "sts-token-url" { + description = "Full URL of the STS token endpoint" + type = string +} + +variable "aliases" { + type = object({ + sts-private-key = string + sts-public-key-id = string + }) + default = { + sts-private-key = "key-1" + sts-public-key-id = "key-1" + } +} + +variable "useSVE" { + type = bool + description = "If true, the -XX:UseSVE=0 switch (Scalable Vector Extensions) will be appended to the JAVA_TOOL_OPTIONS. Can help on macOs on Apple Silicon processors" + default = false +} + +locals { + name = lower(var.humanReadableName) + controlplane-service-name = "${var.humanReadableName}-controlplane" + dataplane-service-name = "${var.humanReadableName}-dataplane" + # HashiCorp Vault KV path-encodes keys; EDC must look up with the same key under which the secret is stored (URL-encoded). + sts_client_secret_alias = urlencode("${var.participantId}-sts-client-secret") +} + +variable "s3_endpoint" { + type = string + description = "S3 endpoint" +} + +# variable "aws_access_key" { +# type = string +# description = "IAM user access key" +# } + +# variable "aws_secret_key" { +# type = string +# description = "IAM user secret key" +# } + +variable "service_account_role_arn" { + type = string + description = "ARN of IAM rol to use as service account; controlplane & dataplane" +} + +variable "controlplane_image" { + type = string + description = "Control Plane container image (tag upgraded in connector-deployment, not Kordat)" +} + +variable "dataplane_image" { + type = string + description = "Data Plane container image (tag upgraded in connector-deployment, not Kordat)" +} + +variable "management_auth_key" { + type = string + description = "Default API key for Management and Catalog APIs (x-api-key). For Kordat-managed participants the key is created once in Kordat and distributed via K8s patch (this value is then overwritten). Use a fixed value for testing or leave default 'password' for seed scripts." + default = "password" +} diff --git a/connector-deployment/modules/iam_role/README.md b/connector-deployment/modules/iam_role/README.md new file mode 100644 index 000000000..8de0fe1b0 --- /dev/null +++ b/connector-deployment/modules/iam_role/README.md @@ -0,0 +1,46 @@ +# iam_role + + +## Requirements + +No requirements. + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | n/a | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_iam_role.role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource | +| [aws_iam_role_policy.policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource | +| [aws_iam_role_policy_attachment.test-attach](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [environment](#input\_environment) | Environment (dev\|pre\|pro) | `string` | n/a | yes | +| [extra\_policies](#input\_extra\_policies) | Extra policies to attach | `list(string)` | `[]` | no | +| [full\_assume\_role\_policy](#input\_full\_assume\_role\_policy) | n/a | `string` | `""` | no | +| [policy\_content](#input\_policy\_content) | Name of the content | `string` | `""` | no | +| [policy\_name](#input\_policy\_name) | Name of the policy | `string` | `""` | no | +| [role](#input\_role) | Role into the product | `string` | n/a | yes | +| [role\_name](#input\_role\_name) | Name of the role | `string` | n/a | yes | +| [role\_principal\_service](#input\_role\_principal\_service) | Principal service of the role | `string` | `""` | no | +| [tenant](#input\_tenant) | Tenant name | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [role\_arn](#output\_role\_arn) | n/a | +| [role\_name](#output\_role\_name) | n/a | + diff --git a/connector-deployment/modules/iam_role/attachments.tf b/connector-deployment/modules/iam_role/attachments.tf new file mode 100644 index 000000000..50422bcca --- /dev/null +++ b/connector-deployment/modules/iam_role/attachments.tf @@ -0,0 +1,5 @@ +resource "aws_iam_role_policy_attachment" "test-attach" { + for_each = toset(var.extra_policies) + role = aws_iam_role.role.id + policy_arn = each.key +} \ No newline at end of file diff --git a/connector-deployment/modules/iam_role/input.tf b/connector-deployment/modules/iam_role/input.tf new file mode 100644 index 000000000..1166a4564 --- /dev/null +++ b/connector-deployment/modules/iam_role/input.tf @@ -0,0 +1,45 @@ +# Common variables +variable "tenant" { + type = string + description = "Tenant name" +} +variable "environment" { + type = string + description = "Environment (dev|pre|pro)" +} +variable "role" { + type = string + description = "Role into the product" +} + +# Role vars +variable "role_name" { + type = string + description = "Name of the role" +} +variable "role_principal_service" { + type = string + description = "Principal service of the role" + default = "" +} +variable "full_assume_role_policy" { + type = string + default = "" +} +variable "policy_name" { + type = string + description = "Name of the policy" + default = "" +} +variable "policy_content" { + type = string + description = "Name of the content" + default = "" +} + +# Additional attachements +variable "extra_policies" { + type = list(string) + description = "Extra policies to attach" + default = [] +} diff --git a/connector-deployment/modules/iam_role/output.tf b/connector-deployment/modules/iam_role/output.tf new file mode 100644 index 000000000..3afc45033 --- /dev/null +++ b/connector-deployment/modules/iam_role/output.tf @@ -0,0 +1,7 @@ +output "role_arn" { + value = aws_iam_role.role.arn +} + +output "role_name" { + value = "${var.tenant}-${var.environment}-${var.role_name}" +} diff --git a/connector-deployment/modules/iam_role/policies.tf b/connector-deployment/modules/iam_role/policies.tf new file mode 100644 index 000000000..97f4c6e53 --- /dev/null +++ b/connector-deployment/modules/iam_role/policies.tf @@ -0,0 +1,7 @@ +resource "aws_iam_role_policy" "policy" { + count = length(var.policy_content) > 0 ? 1 : 0 + name = "${var.tenant}-${var.environment}-${var.policy_name}" + role = aws_iam_role.role.id + + policy = var.policy_content +} diff --git a/connector-deployment/modules/iam_role/role.tf b/connector-deployment/modules/iam_role/role.tf new file mode 100644 index 000000000..35ad20f2f --- /dev/null +++ b/connector-deployment/modules/iam_role/role.tf @@ -0,0 +1,25 @@ +resource "aws_iam_role" "role" { + name = "${var.tenant}-${var.environment}-${var.role_name}" + assume_role_policy = coalesce( + var.full_assume_role_policy, + jsonencode({ + Version = "2012-10-17" + Statement = [ + { + Action = "sts:AssumeRole" + Effect = "Allow" + Principal = { + Service = var.role_principal_service + } + }, + ] + }) + ) + + tags = { + Name = "${var.tenant}-${var.environment}-${var.role_name}" + tenant = var.tenant + environment = var.environment + role = var.role + } +} diff --git a/connector-deployment/modules/identity-hub/ingress.tf b/connector-deployment/modules/identity-hub/ingress.tf new file mode 100644 index 000000000..dfacfac2d --- /dev/null +++ b/connector-deployment/modules/identity-hub/ingress.tf @@ -0,0 +1,81 @@ +# +# Copyright (c) 2023 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 +# + +resource "kubernetes_ingress_v1" "api-ingress" { + metadata { + name = "${var.humanReadableName}-ingress" + namespace = var.namespace + annotations = { + "nginx.ingress.kubernetes.io/rewrite-target" = "/$2" + "nginx.ingress.kubernetes.io/use-regex" = "true" + } + } + spec { + ingress_class_name = "nginx" + rule { + http { + + path { + path = "/${var.service-name}/cs(/|$)(.*)" + backend { + service { + name = kubernetes_service.ih-service.metadata.0.name + port { + number = var.ports.ih-identity-api + } + } + } + } + } + } + } +} + +// the DID endpoint can not actually modify the URL, otherwise it'll mess up the DID resolution +resource "kubernetes_ingress_v1" "did-ingress" { + metadata { + name = "${var.service-name}-did-ingress" + namespace = var.namespace + annotations = { + "nginx.ingress.kubernetes.io/rewrite-target" = "/${var.service-name}/$2" + } + } + + spec { + ingress_class_name = "nginx" + rule { + http { + + + # ingress routes for the DID endpoint + path { + path = "/${var.service-name}(/|&)(.*)" + backend { + service { + name = kubernetes_service.ih-service.metadata.0.name + port { + number = var.ports.ih-did + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/connector-deployment/modules/identity-hub/main.tf b/connector-deployment/modules/identity-hub/main.tf new file mode 100644 index 000000000..52e7b94dd --- /dev/null +++ b/connector-deployment/modules/identity-hub/main.tf @@ -0,0 +1,188 @@ +# +# Copyright (c) 2024 Metaform Systems, Inc. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License, Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# +# Contributors: +# Metaform Systems, Inc. - initial API and implementation +# + +resource "kubernetes_deployment" "identityhub" { + metadata { + name = lower(var.humanReadableName) + namespace = var.namespace + labels = { + App = lower(var.humanReadableName) + } + } + + spec { + replicas = 1 + selector { + match_labels = { + App = lower(var.humanReadableName) + } + } + + template { + metadata { + labels = { + App = lower(var.humanReadableName) + } + } + + spec { + container { + image_pull_policy = "IfNotPresent" + image = var.identityhub_image + name = "identity-hub" + + env_from { + config_map_ref { + name = kubernetes_config_map.identityhub-config.metadata[0].name + } + } + port { + container_port = var.ports.credentials-api + name = "creds-port" + } + + port { + container_port = var.ports.ih-debug + name = "debug" + } + port { + container_port = var.ports.ih-identity-api + name = "identity" + } + port { + container_port = var.ports.ih-did + name = "did" + } + port { + container_port = var.ports.web + name = "default-port" + } + + volume_mount { + mount_path = "/etc/credentials" + name = "credentials-volume" + } + + liveness_probe { + http_get { + path = "/api/check/liveness" + port = var.ports.web + } + failure_threshold = 10 + period_seconds = 5 + timeout_seconds = 30 + } + + readiness_probe { + http_get { + path = "/api/check/readiness" + port = var.ports.web + } + failure_threshold = 10 + period_seconds = 5 + timeout_seconds = 30 + } + + startup_probe { + http_get { + path = "/api/check/startup" + port = var.ports.web + } + failure_threshold = 10 + period_seconds = 5 + timeout_seconds = 30 + } + } + + volume { + name = "credentials-volume" + config_map { + name = kubernetes_config_map.identityhub-credentials-map.metadata[0].name + } + } + } + + } + } +} + + +resource "kubernetes_config_map" "identityhub-credentials-map" { + metadata { + name = "${lower(var.humanReadableName)}-credentials" + namespace = var.namespace + } + + data = { + for f in fileset(var.credentials-dir, "*-credential.json") : f => templatefile(join("/", [var.credentials-dir, f]), + { + did = var.participantId + } + ) + } +} + +resource "kubernetes_config_map" "identityhub-config" { + metadata { + name = "${lower(var.humanReadableName)}-ih-config" + namespace = var.namespace + } + + data = { + # IdentityHub variables + EDC_IH_IAM_ID = var.participantId + EDC_IAM_ISSUER_ID = var.participantId + EDC_IAM_DID_WEB_USE_HTTPS = false + EDC_IH_IAM_PUBLICKEY_ALIAS = local.public-key-alias + EDC_IH_API_SUPERUSER_KEY = var.ih_superuser_apikey + WEB_HTTP_PORT = var.ports.web + WEB_HTTP_PATH = "/api" + WEB_HTTP_IDENTITY_PORT = var.ports.ih-identity-api + WEB_HTTP_IDENTITY_PATH = "/api/identity" + WEB_HTTP_IDENTITY_AUTH_KEY = var.identity_auth_key + WEB_HTTP_CREDENTIALS_PORT = var.ports.credentials-api + WEB_HTTP_CREDENTIALS_PATH = "/api/credentials" + WEB_HTTP_DID_PORT = var.ports.ih-did + WEB_HTTP_DID_PATH = "/" + WEB_HTTP_STS_PORT = var.ports.sts-api + WEB_HTTP_STS_PATH = var.sts-token-path + JAVA_TOOL_OPTIONS = "${var.useSVE ? "-XX:UseSVE=0 " : ""}-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=${var.ports.debug}" + EDC_IAM_STS_PRIVATEKEY_ALIAS = var.aliases.sts-private-key + EDC_IAM_STS_PUBLICKEY_ID = var.aliases.sts-public-key-id + EDC_MVD_CREDENTIALS_PATH = "/etc/credentials/" + EDC_VAULT_HASHICORP_URL = var.vault-url + EDC_VAULT_HASHICORP_TOKEN = var.vault-token + EDC_DATASOURCE_DEFAULT_URL = var.database.url + EDC_DATASOURCE_DEFAULT_USER = var.database.user + EDC_DATASOURCE_DEFAULT_PASSWORD = var.database.password + EDC_SQL_SCHEMA_AUTOCREATE = true + EDC_IAM_ACCESSTOKEN_JTI_VALIDATION = true + + # remote STS configuration + EDC_IAM_STS_OAUTH_TOKEN_URL = "http://${var.humanReadableName}:${var.ports.sts-api}${var.sts-token-path}/token" + EDC_IAM_STS_OAUTH_CLIENT_ID = var.participantId + EDC_IAM_STS_OAUTH_CLIENT_SECRET_ALIAS = urlencode("${var.participantId}-sts-client-secret") + + # Remove participant creation - participants are controlled elsewhere + # Note: EDC_RUNTIME_DISABLED_EXTENSIONS may not prevent initialization if extension + # is in the Docker image classpath. Providing config value as fallback. + EDC_MVD_PARTICIPANTS_LIST_FILE = "/dev/null" + + EDC_CATALOG_CACHE_EXECUTION_ENABLED = "false" + + } +} + +locals { + public-key-alias = "${var.humanReadableName}-publickey" +} diff --git a/connector-deployment/modules/identity-hub/outputs.tf b/connector-deployment/modules/identity-hub/outputs.tf new file mode 100644 index 000000000..007553071 --- /dev/null +++ b/connector-deployment/modules/identity-hub/outputs.tf @@ -0,0 +1,42 @@ +# +# Copyright (c) 2023 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 +# + +output "identity-hub-node-ip" { + value = kubernetes_service.ih-service.spec.0.cluster_ip +} + + +output "ports" { + value = var.ports +} + +output "ih-superuser-apikey" { + value = var.ih_superuser_apikey +} + +output "credentials" { + value = { + path = var.credentials-dir + content = fileset(var.credentials-dir, "*-credential.json") + } +} + +output "sts-token-url" { + value = "http://${kubernetes_service.ih-service.metadata.0.name}:${var.ports.sts-api}${var.sts-token-path}" +} \ No newline at end of file diff --git a/connector-deployment/modules/identity-hub/services.tf b/connector-deployment/modules/identity-hub/services.tf new file mode 100644 index 000000000..65b503930 --- /dev/null +++ b/connector-deployment/modules/identity-hub/services.tf @@ -0,0 +1,46 @@ +# +# Copyright (c) 2024 Metaform Systems, Inc. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License, Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# +# Contributors: +# Metaform Systems, Inc. - initial API and implementation +# + +resource "kubernetes_service" "ih-service" { + metadata { + name = var.humanReadableName + namespace = var.namespace + } + spec { + type = "NodePort" + selector = { + App = kubernetes_deployment.identityhub.spec.0.template.0.metadata[0].labels.App + } + # we need a stable IP, otherwise there will be a cycle with the issuer + port { + name = "credentials" + port = var.ports.credentials-api + } + port { + name = "debug" + port = var.ports.ih-debug + } + port { + name = "management" + port = var.ports.ih-identity-api + } + port { + name = "did" + port = var.ports.ih-did + } + port { + name = "sts" + port = var.ports.sts-api + } + } +} \ No newline at end of file diff --git a/connector-deployment/modules/identity-hub/variables.tf b/connector-deployment/modules/identity-hub/variables.tf new file mode 100644 index 000000000..7c585e363 --- /dev/null +++ b/connector-deployment/modules/identity-hub/variables.tf @@ -0,0 +1,126 @@ +# +# Copyright (c) 2023 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 +# + +## Normally, you shouldn't need to change any values here. If you do, please be sure to also change them in the seed script (seed-k8s.sh). +## Neglecting to do that will render the connectors and identity hubs inoperable! + + +variable "humanReadableName" { + type = string + description = "Human readable name of the connector, NOT the ID!!. Required." +} + +variable "participantId" { + type = string + description = "Participant ID of the connector. Usually a DID" +} + +variable "namespace" { + type = string +} + +variable "ports" { + type = object({ + web = number + debug = number + ih-debug = number + ih-did = number + ih-identity-api = number + credentials-api = number + sts-api = number + }) + default = { + web = 7080 + debug = 1044 + ih-debug = 1044 + ih-did = 7083 + ih-identity-api = 7081 + credentials-api = 7082 + sts-api = 7084 + } +} + +variable "credentials-dir" { + type = string + description = "JSON object containing the credentials to seed, sorted by human-readable participant name" +} + +variable "ih_superuser_apikey" { + default = "c3VwZXItdXNlcg==.c3VwZXItc2VjcmV0LWtleQo=" + description = "Management API Key for the Super-User. Defaults to 'base64(super-user).base64(super-secret-key)" + type = string +} + +variable "vault-url" { + description = "URL of the Hashicorp Vault" + type = string +} + +variable "vault-token" { + default = "root" + description = "This is the authentication token for the vault. DO NOT USE THIS IN PRODUCTION!" + type = string +} + +variable "aliases" { + type = object({ + sts-private-key = string + sts-public-key-id = string + }) + default = { + sts-private-key = "key-1" + sts-public-key-id = "key-1" + } +} + +variable "service-name" { + type = string + description = "Name of the Service endpoint" +} + +variable "database" { + type = object({ + url = string + user = string + password = string + }) +} + +variable "useSVE" { + type = bool + description = "If true, the -XX:UseSVE=0 switch (Scalable Vector Extensions) will be appended to the JAVA_TOOL_OPTIONS. Can help on macOs on Apple Silicon processors" + default = false +} + +variable "sts-token-path" { + description = "path suffix of the STS token API" + type = string + default = "/api/sts" +} + +variable "identityhub_image" { + type = string + description = "Identity Hub container image (tag upgraded in connector-deployment, not Kordat)" +} + +variable "identity_auth_key" { + type = string + description = "API key for Identity API (x-api-key). Default 'password' for backward compatibility; set same as management_auth_key when using a fixed key." + default = "password" +} \ No newline at end of file diff --git a/connector-deployment/modules/kms/README.md b/connector-deployment/modules/kms/README.md new file mode 100644 index 000000000..b2bca74e4 --- /dev/null +++ b/connector-deployment/modules/kms/README.md @@ -0,0 +1,44 @@ +# kms + + +## Requirements + +No requirements. + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | n/a | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_kms_alias.master_key_alias](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource | +| [aws_kms_key.master_key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource | +| [aws_kms_key_policy.master_key_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key_policy) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [alias](#input\_alias) | KMS alias | `string` | `""` | no | +| [environment](#input\_environment) | Environment (dev\|pre\|pro) | `string` | n/a | yes | +| [policy](#input\_policy) | KMS policy | `string` | `""` | no | +| [project](#input\_project) | Project | `string` | n/a | yes | +| [role](#input\_role) | Role into the product | `string` | `"kms"` | no | +| [tags](#input\_tags) | Tags to use | `map(any)` | `{}` | no | +| [tenant](#input\_tenant) | Tenant name | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| [key\_arn](#output\_key\_arn) | n/a | +| [key\_id](#output\_key\_id) | n/a | + diff --git a/connector-deployment/modules/kms/input.tf b/connector-deployment/modules/kms/input.tf new file mode 100644 index 000000000..da60355a3 --- /dev/null +++ b/connector-deployment/modules/kms/input.tf @@ -0,0 +1,25 @@ +# Common variables +variable "environment" { + type = string + description = "Environment (dev|pre|pro)" +} +variable "role" { + type = string + description = "Role into the product" + default = "kms" +} +variable "project" { + type = string + description = "Project" +} +variable "tags" { + type = map(any) + description = "Tags to use" + default = {} +} + +# Config vars +variable "alias" { + type = string + description = "KMS alias" +} \ No newline at end of file diff --git a/connector-deployment/modules/kms/kms.tf b/connector-deployment/modules/kms/kms.tf new file mode 100644 index 000000000..8eb29e6dc --- /dev/null +++ b/connector-deployment/modules/kms/kms.tf @@ -0,0 +1,52 @@ +# Current AWS account +data "aws_caller_identity" "current" {} + +# Create and name kms key +resource "aws_kms_key" "master_key" { + deletion_window_in_days = 15 + enable_key_rotation = true +} + +resource "aws_kms_alias" "master_key_alias" { + name = "alias/${var.alias}" + target_key_id = aws_kms_key.master_key.key_id +} + +resource "aws_kms_key_policy" "master_key_policy" { + key_id = aws_kms_key.master_key.id + policy = jsonencode({ + Version = "2012-10-17" + Statement = [ + # Admin de la key (tu cuenta) + { + Sid = "AllowAccountAdmin" + Effect = "Allow" + Principal = { AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" } + Action = "kms:*" + Resource = "*" + }, + # Permitir a S3 usar la key para este bucket (vía servicio s3 y en tu cuenta) + { + Sid = "AllowS3UseOfKey" + Effect = "Allow" + Principal = { Service = "s3.amazonaws.com" } + Action = [ + "kms:Encrypt", + "kms:Decrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*", + "kms:DescribeKey" + ] + Resource = "*" + Condition = { + StringEquals = { + "kms:CallerAccount" = data.aws_caller_identity.current.account_id + } + StringLike = { + "kms:ViaService" = "s3.eu-west-1.amazonaws.com" + } + } + } + ] + }) +} \ No newline at end of file diff --git a/connector-deployment/modules/kms/output.tf b/connector-deployment/modules/kms/output.tf new file mode 100644 index 000000000..be942d02f --- /dev/null +++ b/connector-deployment/modules/kms/output.tf @@ -0,0 +1,6 @@ +output "key_id" { + value = aws_kms_key.master_key.key_id +} +output "key_arn" { + value = aws_kms_key.master_key.arn +} \ No newline at end of file diff --git a/connector-deployment/modules/s3_bucket/README.md b/connector-deployment/modules/s3_bucket/README.md new file mode 100644 index 000000000..16838d3b0 --- /dev/null +++ b/connector-deployment/modules/s3_bucket/README.md @@ -0,0 +1,79 @@ +# S3 Bucket Module + +Creates a S3 bucket and configure the acl, versioning, encryption and objects ownership. + +## How to use +Include this code in your `main.tf`: + +``` +module "example_bucket" { + source = "./modules/s3_bucket" + project = var.project + environment = var.environment + role = "Descriptive functionality" + bucket_name = "The name of the bucket" + object_ownership = "ObjectWriter" + object_expiration = 90 # Days + acl = "private" + versioning = "Enabled" + encryption = true +} +``` + +## Outputs +The name and arn of the new s3 bucket created +``` +module.example_bucket.bucket_name +module.example_bucket.bucket_arn +``` + + +## Requirements + +No requirements. + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | n/a | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_s3_bucket.bucket](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource | +| [aws_s3_bucket_acl.bucket_acl](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_acl) | resource | +| [aws_s3_bucket_cors_configuration.cors_configuration](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_cors_configuration) | resource | +| [aws_s3_bucket_lifecycle_configuration.lifecycle_configuration](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_lifecycle_configuration) | resource | +| [aws_s3_bucket_ownership_controls.bucket_ownership](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_ownership_controls) | resource | +| [aws_s3_bucket_server_side_encryption_configuration.bucket_encryption](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_server_side_encryption_configuration) | resource | +| [aws_s3_bucket_versioning.bucket_versioning](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [acl](#input\_acl) | Bucket Acl | `string` | `"private"` | no | +| [application](#input\_application) | Role into the product | `string` | n/a | yes | +| [bucket\_name](#input\_bucket\_name) | Bucket Name | `string` | n/a | yes | +| [cors](#input\_cors) | CORS configuration |
object({
apply = bool
allowed_headers = list(string)
allowed_methods = list(string)
allowed_origins = list(string)
expose_headers = list(string)
})
|
{
"allowed_headers": [],
"allowed_methods": [],
"allowed_origins": [],
"apply": false,
"expose_headers": []
}
| no | +| [encryption](#input\_encryption) | Bucket Encryption | `string` | `true` | no | +| [environment](#input\_environment) | Environment (dev\|pre\|pro) | `string` | n/a | yes | +| [lifecycle\_rules](#input\_lifecycle\_rules) | JSON containing rules for lifecycle |
list(object({
id = string
status = string
prefix = string
transitions = list(object({
days = number
storage_class = string
}))
expiration = number
}))
| `[]` | no | +| [object\_ownership](#input\_object\_ownership) | Bucket Objects ownership | `string` | `"ObjectWriter"` | no | +| [project](#input\_project) | project name | `string` | n/a | yes | +| [versioning](#input\_versioning) | Bucket Versioning | `string` | `"Disabled"` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [bucket\_arn](#output\_bucket\_arn) | n/a | +| [bucket\_id](#output\_bucket\_id) | n/a | +| [bucket\_name](#output\_bucket\_name) | n/a | + diff --git a/connector-deployment/modules/s3_bucket/bucket.tf b/connector-deployment/modules/s3_bucket/bucket.tf new file mode 100644 index 000000000..c15e9d03b --- /dev/null +++ b/connector-deployment/modules/s3_bucket/bucket.tf @@ -0,0 +1,135 @@ +resource "aws_s3_bucket" "bucket" { + bucket = "${var.project}-${var.environment}-${var.bucket_name}" + + tags = { + Name = "${var.project}-${var.environment}-${var.bucket_name}" + project = var.project + environment = var.environment + application = var.application + module = "s3_bucket" + } +} + +resource "aws_s3_bucket_ownership_controls" "bucket_ownership" { + bucket = aws_s3_bucket.bucket.id + rule { + object_ownership = var.object_ownership + } +} + +resource "aws_s3_bucket_public_access_block" "this" { + bucket = aws_s3_bucket.bucket.id + block_public_acls = true + block_public_policy = true + ignore_public_acls = true + restrict_public_buckets = true +} + +resource "aws_s3_bucket_acl" "bucket_acl" { + depends_on = [aws_s3_bucket_ownership_controls.bucket_ownership] + + bucket = aws_s3_bucket.bucket.id + acl = var.acl +} + +resource "aws_s3_bucket_versioning" "bucket_versioning" { + bucket = aws_s3_bucket.bucket.id + versioning_configuration { + status = var.versioning + } +} + +resource "aws_s3_bucket_server_side_encryption_configuration" "bucket_encryption" { + bucket = aws_s3_bucket.bucket.id + + rule { + apply_server_side_encryption_by_default { + sse_algorithm = "aws:kms" + kms_master_key_id = var.kms + } + + # Reduce llamadas a KMS y coste en muchos casos + bucket_key_enabled = true + } +} + +resource "aws_s3_bucket_lifecycle_configuration" "lifecycle_configuration" { + count = length(var.lifecycle_rules) > 0 ? 1 : 0 + bucket = aws_s3_bucket.bucket.id + + dynamic "rule" { + for_each = { for each in var.lifecycle_rules : each.id => each } + iterator = rule + content { + id = rule.key + status = rule.value.status + + filter { + prefix = rule.value.prefix + } + dynamic "expiration" { + for_each = rule.value.expiration != 0 ? [1] : [] + iterator = expiration + content { + days = rule.value.expiration + } + } + + dynamic "transition" { + for_each = rule.value.transitions + iterator = transition + + content { + days = transition.value.days + storage_class = transition.value.storage_class + } + } + } + } +} + +resource "aws_s3_bucket_cors_configuration" "cors_configuration" { + count = var.cors.apply ? 1 : 0 + bucket = aws_s3_bucket.bucket.id + + cors_rule { + allowed_headers = var.cors.allowed_headers + allowed_methods = var.cors.allowed_methods + allowed_origins = var.cors.allowed_origins + expose_headers = var.cors.expose_headers + } +} + +# (Opcional) Forzar cifrado: deniega PUT si no viene SSE-KMS con TU key +# resource "aws_s3_bucket_policy" "enforce_kms" { +# bucket = aws_s3_bucket.bucket.id +# policy = jsonencode({ +# Version = "2012-10-17" +# Statement = [ +# { +# Sid = "DenyUnEncryptedObjectUploads" +# Effect = "Deny" +# Principal = "*" +# Action = "s3:PutObject" +# Resource = "${aws_s3_bucket.bucket.arn}/*" +# Condition = { +# StringNotEquals = { +# "s3:x-amz-server-side-encryption" = "aws:kms" +# } +# } +# }, +# { +# Sid = "DenyWrongKMSKey" +# Effect = "Deny" +# Principal = "*" +# Action = "s3:PutObject" +# Resource = "${aws_s3_bucket.bucket.arn}/*" +# Condition = { +# StringNotEquals = { +# "s3:x-amz-server-side-encryption-aws-kms-key-id" = var.kms +# } +# } +# } +# ] +# }) +# } diff --git a/connector-deployment/modules/s3_bucket/input.tf b/connector-deployment/modules/s3_bucket/input.tf new file mode 100644 index 000000000..1d8884cf4 --- /dev/null +++ b/connector-deployment/modules/s3_bucket/input.tf @@ -0,0 +1,69 @@ +# Common variables +variable "project" { + type = string + description = "project name" +} +variable "environment" { + type = string + description = "Environment (dev|pre|pro)" +} +variable "application" { + type = string + description = "Role into the product" +} + +# Bucket variables +variable "bucket_name" { + type = string + description = "Bucket Name" +} +variable "object_ownership" { + type = string + description = "Bucket Objects ownership" + default = "ObjectWriter" +} +variable "lifecycle_rules" { + type = list(object({ + id = string + status = string + prefix = string + transitions = list(object({ + days = number + storage_class = string + })) + expiration = number + })) + description = "JSON containing rules for lifecycle" + default = [] +} + +variable "acl" { + type = string + description = "Bucket Acl" + default = "private" +} +variable "versioning" { + type = string + description = "Bucket Versioning" + default = "Disabled" +} +variable "kms" { + type = string + description = "KMS for Encryption" +} +variable "cors" { + type = object({ + apply = bool + allowed_headers = list(string) + allowed_methods = list(string) + allowed_origins = list(string) + expose_headers = list(string) + }) + description = "CORS configuration" + default = { + apply = false, + allowed_headers = [], + allowed_methods = [], + allowed_origins = [], + expose_headers = [], } +} diff --git a/connector-deployment/modules/s3_bucket/output.tf b/connector-deployment/modules/s3_bucket/output.tf new file mode 100644 index 000000000..833d6bd2a --- /dev/null +++ b/connector-deployment/modules/s3_bucket/output.tf @@ -0,0 +1,11 @@ +output "bucket_name" { + value = aws_s3_bucket.bucket.bucket +} + +output "bucket_arn" { + value = aws_s3_bucket.bucket.arn +} + +output "bucket_id" { + value = aws_s3_bucket.bucket.id +} \ No newline at end of file diff --git a/connector-deployment/modules/vault/variables.tf b/connector-deployment/modules/vault/variables.tf new file mode 100644 index 000000000..1ad67483a --- /dev/null +++ b/connector-deployment/modules/vault/variables.tf @@ -0,0 +1,44 @@ +# +# Copyright (c) 2024 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 +# + +variable "humanReadableName" { + type = string + description = "Human readable name. Should not contain special characters" +} + +variable "namespace" { + type = string +} + +variable "vault-token" { + default = "root" + description = "This is the authentication token for the vault. DO NOT USE THIS IN PRODUCTION!" + type = string +} + +variable "aliases" { + type = object({ + sts-private-key = string + sts-public-key-id = string + }) + default = { + sts-private-key = "key-1" + sts-public-key-id = "key-1" + } +} \ No newline at end of file diff --git a/connector-deployment/modules/vault/vault-values.yaml b/connector-deployment/modules/vault/vault-values.yaml new file mode 100644 index 000000000..e7a5167ed --- /dev/null +++ b/connector-deployment/modules/vault/vault-values.yaml @@ -0,0 +1,22 @@ +# +# Copyright (c) 2024 Metaform Systems, Inc. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License, Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# +# Contributors: +# Metaform Systems, Inc. - initial API and implementation +# + +server: + postStart: +hashicorp: + timeout: 30 + healthCheck: + enabled: true + standbyOk: true + paths: + secret: /v1/secret diff --git a/connector-deployment/modules/vault/vault.tf b/connector-deployment/modules/vault/vault.tf new file mode 100644 index 000000000..371ccf964 --- /dev/null +++ b/connector-deployment/modules/vault/vault.tf @@ -0,0 +1,70 @@ +# +# Copyright (c) 2024 Metaform Systems, Inc. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License, Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0 +# +# SPDX-License-Identifier: Apache-2.0 +# +# Contributors: +# Metaform Systems, Inc. - initial API and implementation +# + +resource "helm_release" "vault" { + name = var.humanReadableName + namespace = var.namespace + + force_update = true + dependency_update = true + reuse_values = true + cleanup_on_fail = true + replace = true + + repository = "https://helm.releases.hashicorp.com" + chart = "vault" + + + + set = [ + { + name = "server.dev.devRootToken" + value = var.vault-token + }, + { + name = "server.dev.enabled" + value = true + }, + { + name = "injector.enabled" + value = false + }, + { + name = "hashicorp.token" + value = var.vault-token + } + ] + + values = [ + file("${path.module}/vault-values.yaml"), + # yamlencode({ + # "server" : { + # "postStart" : [ + # "sh", + # "-c", + # join(" && ", [ + # "sleep 5", + # "/bin/vault kv put secret/${var.aliases.sts-private-key} content=\"${tls_private_key.private_signing_key.private_key_pem}\"", + # # "/bin/vault kv put secret/${local.public-key-alias} content=\"${tls_private_key.ecdsa.public_key_pem}\"" + # ]) + # ] + # } + # }), + ] +} +# +# ECDSA key with P256 elliptic curve +resource "tls_private_key" "private_signing_key" { + algorithm = "ECDSA" + ecdsa_curve = "P256" +} diff --git a/connector-deployment/outputs.tf b/connector-deployment/outputs.tf new file mode 100644 index 000000000..7cb91c950 --- /dev/null +++ b/connector-deployment/outputs.tf @@ -0,0 +1,43 @@ +# +# Copyright (c) 2023 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 +# + +# output "consumer-jdbc-url" { +# # jdbc:postgresql://localhost:5432/mydatabase?currentSchema=myschema +# value = "jdbc:postgresql://${module.consumer-postgres.database-url}/consumer" +# } + +# output "provider-jdbc-url" { +# value = { +# catalog-server = "jdbc:postgresql://${module.provider-postgres.database-url}/catalog_server" +# provider-qna = "jdbc:postgresql://${module.provider-postgres.database-url}/provider_qna" +# provider-manufacturing = "jdbc:postgresql://${module.provider-postgres.database-url}/provider_manufacturing" +# } +# } + +# Participant credentials produced by produce_participant_credentials.sh (run in pipeline before Terraform) +output "participant_public_key_path" { + description = "Path to participant public PEM (assets/_public.pem) for DID doc or backend registration" + value = "${path.module}/assets/${var.participant}_public.pem" +} + +# S3 replication role ARN (use in destination account bucket policy when replicate_to_participant=true) +output "s3_replication_role_arn" { + description = "ARN of the S3 replication role, for use in the destination bucket policy" + value = local.replication_enabled ? module.s3_replication[0].replication_role_arn : null +} \ No newline at end of file diff --git a/connector-deployment/providers.tf b/connector-deployment/providers.tf new file mode 100644 index 000000000..8312f1148 --- /dev/null +++ b/connector-deployment/providers.tf @@ -0,0 +1,57 @@ +# +# Copyright (c) 2023 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 +# + +terraform { + required_providers { + // for generating passwords, clientsecrets etc. + random = { + source = "hashicorp/random" + } + + kubernetes = { + source = "hashicorp/kubernetes" + } + helm = { + // used for Hashicorp Vault + source = "hashicorp/helm" + } + postgresql = { + source = "cyrilgdn/postgresql" + version = "~> 1.26.0" + } + } + + backend "s3" { + region = "eu-west-1" + bucket = "aie-kordat-dev-terraform-remote-state" + key = "infra/kordat//terraform.tfstate" + } + + required_version = ">= 1.13.0" +} + +provider "kubernetes" { + config_path = "~/.kube/config" +} + +provider "helm" { + kubernetes = { + config_path = "~/.kube/config" + } +} diff --git a/connector-deployment/roles.tf b/connector-deployment/roles.tf new file mode 100644 index 000000000..377c214d1 --- /dev/null +++ b/connector-deployment/roles.tf @@ -0,0 +1,88 @@ +module "participant-s3-role" { + source = "./modules/iam_role" + environment = var.environment + tenant = var.project + role = "kordat-participant" + role_name = "${var.participant}-s3-sa-role" + full_assume_role_policy = </dev/null; then + echo " ✅ super-user-apikey exists" +else + echo " ➕ Adding super-user-apikey..." + kubectl exec -n $NAMESPACE $VAULT_POD -- vault kv put secret/super-user-apikey content="$API_KEY" > /dev/null + echo " ✅ Added super-user-apikey" + NEEDS_IH_RESTART=true +fi + +echo "" + +# ========================================== +# Step 2: Check/create dataspace-issuer ExternalName services +# ========================================== +echo "Step 2: Checking dataspace-issuer services..." + +if kubectl get service dataspace-issuer -n $NAMESPACE &>/dev/null; then + echo " ✅ dataspace-issuer service exists" +else + echo " ➕ Creating dataspace-issuer service..." + kubectl apply -f - </dev/null +apiVersion: v1 +kind: Service +metadata: + name: dataspace-issuer + namespace: $NAMESPACE +spec: + type: ExternalName + externalName: dataspace-issuer.kordat.svc.cluster.local +EOF + echo " ✅ Created dataspace-issuer service" +fi + +if kubectl get service dataspace-issuer-service -n $NAMESPACE &>/dev/null; then + echo " ✅ dataspace-issuer-service exists" +else + echo " ➕ Creating dataspace-issuer-service..." + kubectl apply -f - </dev/null +apiVersion: v1 +kind: Service +metadata: + name: dataspace-issuer-service + namespace: $NAMESPACE +spec: + type: ExternalName + externalName: dataspace-issuer-service.kordat.svc.cluster.local +EOF + echo " ✅ Created dataspace-issuer-service" +fi + +echo "" + +# ========================================== +# Step 3: Restart IdentityHub if needed +# ========================================== +if [ "$NEEDS_IH_RESTART" = true ]; then + echo "Step 3: Restarting IdentityHub to pick up vault changes..." + IH_POD=$(kubectl get pods -n $NAMESPACE | grep identityhub | grep Running | head -1 | awk '{print $1}') + if [ -n "$IH_POD" ]; then + kubectl delete pod -n $NAMESPACE $IH_POD &>/dev/null + echo " ✅ IdentityHub pod deleted, waiting for restart..." + sleep 5 + fi +else + echo "Step 3: IdentityHub restart not needed" +fi + +echo "" + +# ========================================== +# Step 4: Wait for identityhub to be ready +# ========================================== +echo "Step 4: Waiting for identityhub to be ready..." + +for i in {1..60}; do + IDENTITYHUB_POD=$(kubectl get pods -n $NAMESPACE | grep identityhub | grep Running | head -1 | awk '{print $1}' 2>/dev/null) + if [ -n "$IDENTITYHUB_POD" ]; then + if kubectl exec -n $NAMESPACE $IDENTITYHUB_POD -- curl -s -f http://localhost:7080/api/check/health &>/dev/null; then + echo " ✅ IdentityHub ready: $IDENTITYHUB_POD" + break + fi + fi + if [ $i -eq 60 ]; then + echo " ⚠️ IdentityHub not ready after 60 seconds, continuing anyway..." + IDENTITYHUB_POD=$(kubectl get pods -n $NAMESPACE | grep identityhub | head -1 | awk '{print $1}') + if [ -z "$IDENTITYHUB_POD" ]; then + echo " ❌ No IdentityHub pod found" + exit 1 + fi + fi + sleep 1 +done + +echo "" + +# ========================================== +# Step 5: Check STS client secret and register if missing +# ========================================== +echo "Step 5: Checking STS client secret..." + +STS_SECRET="did%3Aweb%3A${NAMESPACE}-identityhub.${NAMESPACE}%253A7083%3A${NAMESPACE}-sts-client-secret" +STS_SECRET_SHORT="${NAMESPACE}-sts-client-secret" +STS_SECRET_RAW="did:web:${NAMESPACE}-identityhub.${NAMESPACE}%3A7083:${NAMESPACE}-sts-client-secret" + +if kubectl exec -n $NAMESPACE $VAULT_POD -- vault kv get "secret/$STS_SECRET_RAW" &>/dev/null; then + SECRET_VALUE=$(kubectl exec -n $NAMESPACE $VAULT_POD -- vault kv get -field=content "secret/$STS_SECRET_RAW" 2>/dev/null) +elif kubectl exec -n $NAMESPACE $VAULT_POD -- vault kv get "secret/$STS_SECRET" &>/dev/null; then + SECRET_VALUE=$(kubectl exec -n $NAMESPACE $VAULT_POD -- vault kv get -field=content "secret/$STS_SECRET" 2>/dev/null) +fi + +if [ -n "$SECRET_VALUE" ]; then + echo " ✅ STS client secret exists: $SECRET_VALUE" + if ! kubectl exec -n $NAMESPACE $VAULT_POD -- vault kv get "secret/$STS_SECRET_RAW" &>/dev/null; then + echo " ➕ Storing STS client secret under raw alias (EDC lookup)..." + kubectl exec -n $NAMESPACE $VAULT_POD -- sh -c "vault kv put 'secret/$STS_SECRET_RAW' content='$SECRET_VALUE'" &>/dev/null + echo " ✅ Raw alias stored" + NEEDS_IH_RESTART=true + fi + if ! kubectl exec -n $NAMESPACE $VAULT_POD -- vault kv get "secret/$STS_SECRET_SHORT" &>/dev/null; then + echo " ➕ Storing STS client secret under short alias..." + kubectl exec -n $NAMESPACE $VAULT_POD -- vault kv put "secret/$STS_SECRET_SHORT" content="$SECRET_VALUE" &>/dev/null + echo " ✅ Short alias $STS_SECRET_SHORT stored" + NEEDS_IH_RESTART=true + fi +else + echo " ➕ STS client secret missing, registering participant..." + + PARTICIPANT_ID=$(kubectl exec -n kordat $BACKEND_POD -- python -c " +import django +import os +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'kordat.settings') +django.setup() + +from participants.models import Participant +try: + p = Participant.objects.get(short_name='$NAMESPACE') + print(p.id) +except Participant.DoesNotExist: + print('NOT_FOUND') +" 2>/dev/null) + + if [ "$PARTICIPANT_ID" == "NOT_FOUND" ]; then + echo " ❌ Participant '$NAMESPACE' not found in database" + exit 1 + fi + + echo " ✅ Found participant ID: $PARTICIPANT_ID" + + RESULT=$(kubectl exec -n kordat $BACKEND_POD -- python -c " +import django +import os +import json +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'kordat.settings') +django.setup() + +from participants.services.participant import register_participant_in_identityhub + +result = register_participant_in_identityhub('$PARTICIPANT_ID') +print(json.dumps(result, indent=2, default=str)) +" 2>&1) + + if echo "$RESULT" | grep -q '"status": "success"'; then + echo " ✅ Registration successful!" + elif echo "$RESULT" | grep -q '"status": "exists"'; then + echo " ✅ Participant already registered!" + else + echo " ⚠️ Registration status unclear, continuing..." + fi + + if kubectl exec -n $NAMESPACE $VAULT_POD -- vault kv get "secret/$STS_SECRET_RAW" &>/dev/null; then + SECRET_VALUE=$(kubectl exec -n $NAMESPACE $VAULT_POD -- vault kv get -field=content "secret/$STS_SECRET_RAW" 2>/dev/null) + echo " ✅ STS client secret now exists: $SECRET_VALUE" + elif kubectl exec -n $NAMESPACE $VAULT_POD -- vault kv get "secret/$STS_SECRET" &>/dev/null; then + SECRET_VALUE=$(kubectl exec -n $NAMESPACE $VAULT_POD -- vault kv get -field=content "secret/$STS_SECRET" 2>/dev/null) + echo " ✅ STS client secret now exists: $SECRET_VALUE" + kubectl exec -n $NAMESPACE $VAULT_POD -- sh -c "vault kv put 'secret/$STS_SECRET_RAW' content='$SECRET_VALUE'" &>/dev/null + echo " ✅ Stored under raw alias for EDC" + else + echo " ⚠️ STS client secret not created automatically" + echo " ➕ Generating and storing STS client secret manually..." + + CLIENT_SECRET=$(tr -dc 'A-Za-z0-9' /dev/null + kubectl exec -n $NAMESPACE $VAULT_POD -- sh -c "vault kv put 'secret/$STS_SECRET_RAW' content='$CLIENT_SECRET'" &>/dev/null + kubectl exec -n $NAMESPACE $VAULT_POD -- vault kv put "secret/$STS_SECRET_SHORT" content="$CLIENT_SECRET" &>/dev/null + + if kubectl exec -n $NAMESPACE $VAULT_POD -- vault kv get "secret/$STS_SECRET_RAW" &>/dev/null; then + echo " ✅ Created STS client secret: $CLIENT_SECRET" + + kubectl exec -n kordat $BACKEND_POD -- python -c " +import django +import os +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'kordat.settings') +django.setup() + +from participants.models import Participant + +p = Participant.objects.get(short_name='$NAMESPACE') +metadata = p.metadata or {} +metadata['client_secret'] = '$CLIENT_SECRET' +p.metadata = metadata +p.save() +print('✅ Stored client_secret in participant metadata') +" 2>&1 | grep "✅" + else + echo " ❌ Failed to create STS client secret in vault" + fi + fi +fi + +echo "" + +# ========================================== +# Step 6: Check and delete corrupted credentials +# ========================================== +echo "Step 6: Checking for corrupted credentials..." + +RESPONSE=$(kubectl exec -n $NAMESPACE $IDENTITYHUB_POD -- curl -s \ + -H "x-api-key: $API_KEY" \ + "http://localhost:7081/api/identity/v1alpha/participants/did:web:${PARTICIPANT}-identityhub.${NAMESPACE}%3A7083:${PARTICIPANT}/credentials" 2>&1) + +if echo "$RESPONSE" | grep -q "HTTP ERROR"; then + echo " ⚠️ Could not fetch credentials (API may still be initializing)" +else + TOTAL=$(echo "$RESPONSE" | jq '. | length' 2>/dev/null || echo "0") + BAD=$(echo "$RESPONSE" | jq --arg expected "did:web:${PARTICIPANT}-identityhub.${NAMESPACE}%3A7083:${PARTICIPANT}" '[.[] | select((.verifiableCredential.rawVc | split(".")[1] | @base64d | fromjson | .vc.credentialSubject.id) != $expected)] | length' 2>/dev/null || echo "0") + + echo " Total credentials: $TOTAL" + echo " Corrupted credentials: $BAD" + + if [ "$BAD" -gt 0 ]; then + echo " 🗑️ Deleting corrupted credentials..." + CORRUPTED_IDS=$(echo "$RESPONSE" | jq -r --arg expected "did:web:${PARTICIPANT}-identityhub.${NAMESPACE}%3A7083:${PARTICIPANT}" ' + .[] | + select((.verifiableCredential.rawVc | split(".")[1] | @base64d | fromjson | .vc.credentialSubject.id) != $expected) | + .id + ') + for CRED_ID in $CORRUPTED_IDS; do + echo " Deleting: $CRED_ID" + kubectl exec -n $NAMESPACE $IDENTITYHUB_POD -- \ + curl -s -X DELETE \ + -H "x-api-key: $API_KEY" \ + "http://localhost:7081/api/identity/v1alpha/participants/did:web:${PARTICIPANT}-identityhub.${NAMESPACE}%3A7083:${PARTICIPANT}/credentials/${CRED_ID}" > /dev/null + done + echo " ✅ Deleted $BAD corrupted credential(s)" + else + echo " ✅ No corrupted credentials found" + fi +fi + +echo "" + +# ========================================== +# Step 7: Final verification +# ========================================== +echo "Step 7: Final verification..." + +if ! kubectl exec -n $NAMESPACE $VAULT_POD -- vault kv get "secret/$STS_SECRET_RAW" &>/dev/null; then + echo "❌ STS client secret missing (raw alias - EDC uses this)" +else + echo "✅ SUCCESS: $NAMESPACE is fully configured!" + echo " STS client secret present under raw alias." +fi + +echo "" diff --git a/connector-deployment/scripts/produce_participant_credentials.sh b/connector-deployment/scripts/produce_participant_credentials.sh new file mode 100755 index 000000000..b52cad887 --- /dev/null +++ b/connector-deployment/scripts/produce_participant_credentials.sh @@ -0,0 +1,77 @@ +#!/bin/bash +# Produce participant PEM (private key) and signed -credential.json from participant_id. +# Tested with: public.ecr.aws/codebuild/amazonlinux-x86_64-standard:5.0 (jq, openssl preinstalled). +# Requirements: jq, openssl (on other AL images: dnf install -y jq) +# +# Usage: produce_participant_credentials.sh [output_dir] [dataspace_issuer_did] +# Example: produce_participant_credentials.sh testcloud4 +# Output: assets/_private.pem, assets/_public.pem; assets/credentials/k8s//*-credential.json +set -e + +# Require jq and openssl (amazonlinux-x86_64-standard:5.0 has both; else: dnf install -y jq) +command -v jq >/dev/null 2>&1 || { echo "Missing: jq. On Amazon Linux: dnf install -y jq" >&2; exit 1; } +command -v openssl >/dev/null 2>&1 || { echo "Missing: openssl" >&2; exit 1; } + +PARTICIPANT_ID="${1}" +OUT_DIR_ARG="${2}" +DATASPACE_ISSUER_DID="${3:-did:web:dataspace-issuer}" + +ISSUANCEDATE_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") +TIMESTAMP=$(date -u +%s) + +[ -z "$PARTICIPANT_ID" ] && { echo "Usage: $0 [output_dir] [dataspace_issuer_did]" >&2; exit 1; } + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +CONNECTOR_DEPLOYMENT="$(cd "$SCRIPT_DIR/.." && pwd)" +CREDENTIALS_DIR="$CONNECTOR_DEPLOYMENT/assets/credentials" +TEMPLATE_DIR="$CREDENTIALS_DIR/k8s/participant" +OUT_DIR="${OUT_DIR_ARG:-$CREDENTIALS_DIR/k8s/$PARTICIPANT_ID}" +ISSUER_PEM="${ISSUER_PEM:-$CONNECTOR_DEPLOYMENT/assets/issuer_private.pem}" +SIGN_VC_SH="${SIGN_VC_SH:-$SCRIPT_DIR/sign_vc.sh}" +[ ! -f "$SIGN_VC_SH" ] && { echo "sign_vc.sh not found: $SIGN_VC_SH (set SIGN_VC_SH)" >&2; exit 1; } +[ ! -f "$ISSUER_PEM" ] && { echo "Issuer key not found: $ISSUER_PEM (set ISSUER_PEM)" >&2; exit 1; } +ASSETS_DIR="$CONNECTOR_DEPLOYMENT/assets" +mkdir -p "$OUT_DIR" +mkdir -p "$ASSETS_DIR" + +PARTICIPANT_PRIVATE_PEM="$ASSETS_DIR/${PARTICIPANT_ID}_private.pem" +PARTICIPANT_PUBLIC_PEM="$ASSETS_DIR/${PARTICIPANT_ID}_public.pem" + +# 1) Generate participant EC P256 private key and public key in assets/ +openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out "$PARTICIPANT_PRIVATE_PEM" 2>/dev/null +openssl pkey -in "$PARTICIPANT_PRIVATE_PEM" -pubout -out "$PARTICIPANT_PUBLIC_PEM" 2>/dev/null +echo "Wrote $PARTICIPANT_PRIVATE_PEM" +echo "Wrote $PARTICIPANT_PUBLIC_PEM" + +# 2) Substitute in templates and sign VC; build credential JSON +# Variables: , , , , +subst_vc() { + sed -e "s||$PARTICIPANT_ID|g" \ + -e "s||$ISSUANCEDATE_DATE|g" \ + -e "s||$DATASPACE_ISSUER_DID|g" \ + "$1" +} +subst_cred() { + sed -e "s||$PARTICIPANT_ID|g" \ + -e "s||$CRED_ID|g" \ + -e "s||$TIMESTAMP|g" \ + -e "s||$DATASPACE_ISSUER_DID|g" \ + "$1" +} +# Portable UUID (Linux /proc first, then uuidgen, no dependency on util-linux in minimal images) +gen_uuid() { cat /proc/sys/kernel/random/uuid 2>/dev/null || uuidgen 2>/dev/null || echo "00000000-0000-0000-0000-000000000000"; } + +for kind in dataprocessor membership; do + VC_TMP=$(mktemp) + subst_vc "$TEMPLATE_DIR/${kind}_vc.json" > "$VC_TMP" + JWT=$("$SIGN_VC_SH" "$VC_TMP" "$ISSUER_PEM") + rm -f "$VC_TMP" + CRED_ID=$(gen_uuid) + CRED_TMP=$(mktemp) + JWT_TMP=$(mktemp) + printf '%s' "$JWT" > "$JWT_TMP" + subst_cred "$TEMPLATE_DIR/${kind}-credential.json" > "$CRED_TMP" + jq --rawfile raw "$JWT_TMP" '.verifiableCredential.rawVc = $raw' "$CRED_TMP" > "$OUT_DIR/${kind}-credential.json" + rm -f "$CRED_TMP" "$JWT_TMP" + echo "Wrote $OUT_DIR/${kind}-credential.json" +done diff --git a/connector-deployment/scripts/seed_vault_participant_key.sh b/connector-deployment/scripts/seed_vault_participant_key.sh new file mode 100644 index 000000000..771631b3f --- /dev/null +++ b/connector-deployment/scripts/seed_vault_participant_key.sh @@ -0,0 +1,34 @@ +#!/bin/bash +# Seed the participant's private key (PEM) into the participant namespace Vault. +# Key path matches EDC alias: did:web:{participant}-identityhub.{participant}%3A7083:{participant}#key-1 +# (URL-encoded in Vault as secret/KEY) +# +# Usage: ./seed_vault_participant_key.sh PARTICIPANT [path_to_private_pem] +# Default PEM: ./assets/_private.pem (relative to connector-deployment) +# Run from: connector-deployment/ (or set PEM path explicitly) +set -e + +PARTICIPANT="${1}" +PEM_PATH="${2:-$(dirname "$0")/../assets/${PARTICIPANT}_private.pem}" +NS="${PARTICIPANT}" + +[ -z "$PARTICIPANT" ] && { echo "Usage: $0 PARTICIPANT [path_to_private_pem]" >&2; exit 1; } +[ ! -f "$PEM_PATH" ] && { echo "PEM not found: $PEM_PATH" >&2; exit 1; } + +# Vault secret key (URL-encoded DID#key-1, same as participant_vault_csv.sh / EDC) +PREFIX="did%3Aweb%3A${PARTICIPANT}-identityhub.${PARTICIPANT}%253A7083%3A${PARTICIPANT}" +VAULT_KEY="${PREFIX}%23key-1" + +echo "Waiting for Vault pod in namespace $NS..." +for i in $(seq 1 30); do + VAULT_POD=$(kubectl get pods -n "$NS" -l app.kubernetes.io/name=vault -o jsonpath='{.items[0].metadata.name}' 2>/dev/null || true) + [ -n "$VAULT_POD" ] && kubectl get pod -n "$NS" "$VAULT_POD" -o jsonpath='{.status.phase}' 2>/dev/null | grep -q Running && break + sleep 2 +done +[ -z "$VAULT_POD" ] && { echo "Vault pod not found in $NS" >&2; exit 1; } + +TMP_IN_POD="/tmp/participant_key_$$.pem" +kubectl cp "$PEM_PATH" "$NS/$VAULT_POD:$TMP_IN_POD" +kubectl exec -n "$NS" "$VAULT_POD" -- vault kv put "secret/$VAULT_KEY" content=@"$TMP_IN_POD" +kubectl exec -n "$NS" "$VAULT_POD" -- rm -f "$TMP_IN_POD" 2>/dev/null || true +echo "Seeded Vault secret/$VAULT_KEY from $PEM_PATH" diff --git a/connector-deployment/scripts/sign_vc.sh b/connector-deployment/scripts/sign_vc.sh new file mode 100755 index 000000000..d5ececb79 --- /dev/null +++ b/connector-deployment/scripts/sign_vc.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# Sign a verifiable credential JSON with the dataspace-issuer key. Outputs JWT to stdout. +# Usage: sign_vc.sh [issuer_private.pem] +# Issuer DID and subject (aud/sub) are taken from the VC (issuer, credentialSubject.id). + +set -e +VC="$1" +KEY="${2:-$(cd "$(dirname "$0")/.." && pwd)/assets/issuer_private.pem}" +[ -z "$VC" ] || [ ! -f "$VC" ] && { echo "Usage: $0 [issuer_private.pem]" >&2; exit 1; } +[ ! -f "$KEY" ] && { echo "Key not found: $KEY" >&2; exit 1; } + +b64url() { base64 -w 0 2>/dev/null | tr '+/' '-_' | tr -d '=' || base64 | tr -d '\n' | tr '+/' '-_' | tr -d '='; } + +ISSUER=$(jq -r '.issuer // "did:web:dataspace-issuer"' "$VC") +SUBJECT=$(jq -r '.credentialSubject.id // .credentialSubject[0].id // empty' "$VC") +[ -z "$SUBJECT" ] && SUBJECT="$ISSUER" + +HEADER=$(jq -nc --arg kid "${ISSUER}#key-1" '{alg:"EdDSA",kid:$kid,typ:"JWT"}') +PAYLOAD=$(jq -nc --arg iss "$ISSUER" --arg aud "$SUBJECT" --arg sub "$SUBJECT" --slurpfile vc "$VC" '{iss:$iss,aud:$aud,sub:$sub,vc:($vc[0]),iat:(now|floor)}') + +B64H=$(echo -n "$HEADER" | b64url) +B64P=$(echo -n "$PAYLOAD" | b64url) +SIGN_INPUT="${B64H}.${B64P}" +TMP=$(mktemp) +trap "rm -f $TMP ${TMP}.msg" EXIT +printf '%s' "$SIGN_INPUT" > "${TMP}.msg" +# Ed25519 (EdDSA) requires -rawin in OpenSSL 3.x (CodeBuild amazonlinux image) +openssl pkeyutl -sign -inkey "$KEY" -in "${TMP}.msg" -out "$TMP" -rawin +SIG=$(base64 -w 0 "$TMP" 2>/dev/null | tr '+/' '-_' | tr -d '=' || base64 < "$TMP" | tr -d '\n' | tr '+/' '-_' | tr -d '=') +echo "${SIGN_INPUT}.${SIG}" diff --git a/connector-deployment/terraform.tfvars b/connector-deployment/terraform.tfvars new file mode 100644 index 000000000..8c6a44c80 --- /dev/null +++ b/connector-deployment/terraform.tfvars @@ -0,0 +1,9 @@ +participant = "" +environment = "" +postgres_admin_password = "" +participant_management_auth_key = "" + +# S3 replication - substituted by pipeline (connector-up-apply.yml) +replicate_to_participant = +participant_account_id = "" +participant_bucket_name = "" \ No newline at end of file diff --git a/connector-deployment/variables.tf b/connector-deployment/variables.tf new file mode 100644 index 000000000..d651b65ab --- /dev/null +++ b/connector-deployment/variables.tf @@ -0,0 +1,96 @@ +# +# Copyright (c) 2023 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 +# + +variable "participant" { + type = string +} + +variable "environment" { + type = string +} + +variable "postgres_endpoint" { + type = string + default = "kordat-dev-participants-database.cnsm066acc36.eu-west-1.rds.amazonaws.com" +} + +variable "postgres_port" { + type = number + default = 5432 +} + +variable "postgres_admin_password" { + type = string +} + +variable "project" { + type = string + default = "kordat" +} + +variable "useSVE" { + type = bool + description = "If true, the -XX:UseSVE=0 switch (Scalable Vector Extensions) will be added to the JAVA_TOOL_OPTIONS. Can help on macOs on Apple Silicon processors" + default = false +} + +# MVD component image versions are upgraded here (connector-deployment), not in the Kordat project. +# The Control Plane stores STS client secrets in Vault; upgrading its image may change Vault key behaviour. +variable "controlplane_image" { + type = string + description = "Control Plane (connector) image. Upgrade tag here when releasing new MVD/EDC versions." + default = "150073872684.dkr.ecr.eu-west-1.amazonaws.com/kordat-dev-controlplane:012e96ac" +} + +variable "dataplane_image" { + type = string + description = "Data Plane image. Upgrade tag here when releasing new MVD/EDC versions." + default = "150073872684.dkr.ecr.eu-west-1.amazonaws.com/kordat-dev-dataplane:012e96ac" +} + +variable "identityhub_image" { + type = string + description = "Identity Hub image. Upgrade tag here when releasing new MVD/EDC versions." + default = "150073872684.dkr.ecr.eu-west-1.amazonaws.com/kordat-dev-identity-hub:012e96ac" +} + +variable "participant_management_auth_key" { + type = string + description = "Default API key for this participant's connector. For Kordat-managed participants the key is created once in Kordat and distributed via K8s patch (this default is overwritten). Set a fixed value for testing; default 'password' for seed scripts." + default = "password" +} + +# S3 replication (isolated per participant - only created when all three are set) +variable "replicate_to_participant" { + type = bool + description = "Enable replication from this participant's bucket to a destination participant bucket" + default = false +} + +variable "participant_account_id" { + type = string + description = "Destination AWS account ID for replication (e.g. GDM account)" + default = "" +} + +variable "participant_bucket_name" { + type = string + description = "Destination bucket name in the participant account (e.g. gdm-pre-backend-bucket)" + default = "" +} diff --git a/deployment/assets/credentials/k8s/consumer/dataprocessor-credential.json b/deployment/assets/credentials/k8s/consumer/dataprocessor-credential.json index f7c8f50dc..496b00182 100644 --- a/deployment/assets/credentials/k8s/consumer/dataprocessor-credential.json +++ b/deployment/assets/credentials/k8s/consumer/dataprocessor-credential.json @@ -9,7 +9,7 @@ "reissuancePolicy": null, "verifiableCredential": { "format": "VC1_0_JWT", - "rawVc": "eyJraWQiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIja2V5LTEiLCJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJpc3MiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIiLCJhdWQiOiJkaWQ6d2ViOmNvbnN1bWVyLWlkZW50aXR5aHViJTNBNzA4MzphbGljZSIsInN1YiI6ImRpZDp3ZWI6Y29uc3VtZXItaWRlbnRpdHlodWIlM0E3MDgzOmFsaWNlIiwidmMiOnsiQGNvbnRleHQiOlsiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvdjEiLCJodHRwczovL3czaWQub3JnL3NlY3VyaXR5L3N1aXRlcy9qd3MtMjAyMC92MSIsImh0dHBzOi8vd3d3LnczLm9yZy9ucy9kaWQvdjEiLHsibXZkLWNyZWRlbnRpYWxzIjoiaHR0cHM6Ly93M2lkLm9yZy9tdmQvY3JlZGVudGlhbHMvIiwiY29udHJhY3RWZXJzaW9uIjoibXZkLWNyZWRlbnRpYWxzOmNvbnRyYWN0VmVyc2lvbiIsImxldmVsIjoibXZkLWNyZWRlbnRpYWxzOmxldmVsIn1dLCJpZCI6Imh0dHA6Ly9vcmcueW91cmRhdGFzcGFjZS5jb20vY3JlZGVudGlhbHMvMjM0NyIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJEYXRhUHJvY2Vzc29yQ3JlZGVudGlhbCJdLCJpc3N1ZXIiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIiLCJpc3N1YW5jZURhdGUiOiIyMDIzLTA4LTE4VDAwOjAwOjAwWiIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOndlYjpjb25zdW1lci1pZGVudGl0eWh1YiUzQTcwODM6Y29uc3VtZXIiLCJjb250cmFjdFZlcnNpb24iOiIxLjAuMCIsImxldmVsIjoicHJvY2Vzc2luZyJ9fSwiaWF0IjoxNzQ4ODQ0OTE5fQ.Asd_5HEu-UaV3bSZ3DlkIlI5yiAik18JcAtKwK6HVx3MAW5uR907lEJfgdO29eHfTR9_qiHG5OitXYCpL_sxBQ", + "rawVc": "eyJraWQiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIja2V5LTEiLCJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJpc3MiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIiLCJhdWQiOiJkaWQ6d2ViOmNvbnN1bWVyLWlkZW50aXR5aHViJTNBNzA4MzphbGljZSIsInN1YiI6ImRpZDp3ZWI6Y29uc3VtZXItaWRlbnRpdHlodWIlM0E3MDgzOmFsaWNlIiwidmMiOnsiQGNvbnRleHQiOlsiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvdjEiLCJodHRwczovL3czaWQub3JnL3NlY3VyaXR5L3N1aXRlcy9qd3MtMjAyMC92MSIsImh0dHBzOi8vd3d3LnczLm9yZy9ucy9kaWQvdjEiLHsibXZkLWNyZWRlbnRpYWxzIjoiaHR0cHM6Ly93M2lkLm9yZy9tdmQvY3JlZGVudGlhbHMvIiwiY29udHJhY3RWZXJzaW9uIjoibXZkLWNyZWRlbnRpYWxzOmNvbnRyYWN0VmVyc2lvbiIsImxldmVsIjoibXZkLWNyZWRlbnRpYWxzOmxldmVsIn1dLCJpZCI6Imh0dHA6Ly9vcmcueW91cmRhdGFzcGFjZS5jb20vY3JlZGVudGlhbHMvMjM0NyIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJEYXRhUHJvY2Vzc29yQ3JlZGVudGlhbCJdLCJpc3N1ZXIiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIiLCJpc3N1YW5jZURhdGUiOiIyMDIzLTA4LTE4VDAwOjAwOjAwWiIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOndlYjpjb25zdW1lci1pZGVudGl0eWh1YiUzQTcwODM6Y29uc3VtZXIiLCJjb250cmFjdFZlcnNpb24iOiIxLjAuMCIsImxldmVsIjoicHJvY2Vzc2luZyJ9fSwiaWF0IjoxNzY5NTExMDc4fQ.WNMOSZVwMf3TDETcIXEsREZceVxEmNyTW6Mq2onQWiQRAS7uvGb-X7ZLwtpWtsxzVhjqdx2-0vJM77Rpu0xDAA", "credential": { "credentialSubject": [ { diff --git a/deployment/assets/credentials/k8s/consumer/membership-credential.json b/deployment/assets/credentials/k8s/consumer/membership-credential.json index c8d45368d..fa69143a9 100644 --- a/deployment/assets/credentials/k8s/consumer/membership-credential.json +++ b/deployment/assets/credentials/k8s/consumer/membership-credential.json @@ -8,7 +8,7 @@ "issuancePolicy": null, "reissuancePolicy": null, "verifiableCredential": { - "rawVc": "eyJraWQiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIja2V5LTEiLCJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJpc3MiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIiLCJhdWQiOiJkaWQ6d2ViOmNvbnN1bWVyLWlkZW50aXR5aHViJTNBNzA4MzphbGljZSIsInN1YiI6ImRpZDp3ZWI6Y29uc3VtZXItaWRlbnRpdHlodWIlM0E3MDgzOmFsaWNlIiwidmMiOnsiQGNvbnRleHQiOlsiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvdjEiLCJodHRwczovL3czaWQub3JnL3NlY3VyaXR5L3N1aXRlcy9qd3MtMjAyMC92MSIsImh0dHBzOi8vd3d3LnczLm9yZy9ucy9kaWQvdjEiLHsibXZkLWNyZWRlbnRpYWxzIjoiaHR0cHM6Ly93M2lkLm9yZy9tdmQvY3JlZGVudGlhbHMvIiwibWVtYmVyc2hpcCI6Im12ZC1jcmVkZW50aWFsczptZW1iZXJzaGlwIiwibWVtYmVyc2hpcFR5cGUiOiJtdmQtY3JlZGVudGlhbHM6bWVtYmVyc2hpcFR5cGUiLCJ3ZWJzaXRlIjoibXZkLWNyZWRlbnRpYWxzOndlYnNpdGUiLCJjb250YWN0IjoibXZkLWNyZWRlbnRpYWxzOmNvbnRhY3QiLCJzaW5jZSI6Im12ZC1jcmVkZW50aWFsczpzaW5jZSJ9XSwiaWQiOiJodHRwOi8vb3JnLnlvdXJkYXRhc3BhY2UuY29tL2NyZWRlbnRpYWxzLzIzNDciLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiTWVtYmVyc2hpcENyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOndlYjpkYXRhc3BhY2UtaXNzdWVyIiwiaXNzdWFuY2VEYXRlIjoiMjAyMy0wOC0xOFQwMDowMDowMFoiLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDp3ZWI6Y29uc3VtZXItaWRlbnRpdHlodWIlM0E3MDgzOmNvbnN1bWVyIiwibWVtYmVyc2hpcCI6eyJtZW1iZXJzaGlwVHlwZSI6IkZ1bGxNZW1iZXIiLCJ3ZWJzaXRlIjoid3d3LndoYXRldmVyLmNvbSIsImNvbnRhY3QiOiJmaXp6LmJ1enpAd2hhdGV2ZXIuY29tIiwic2luY2UiOiIyMDIzLTAxLTAxVDAwOjAwOjAwWiJ9fX0sImlhdCI6MTc0ODg0NDkxOX0.xcb9qKJ_BGGj_KvSM9lZIdJW01FSdDjALXxhmH8CehkOPy2nXGnWKIbjHJZmW60NtU7kqRC23THU7OWFs28EDw", + "rawVc": "eyJraWQiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIja2V5LTEiLCJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJpc3MiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIiLCJhdWQiOiJkaWQ6d2ViOmNvbnN1bWVyLWlkZW50aXR5aHViJTNBNzA4MzphbGljZSIsInN1YiI6ImRpZDp3ZWI6Y29uc3VtZXItaWRlbnRpdHlodWIlM0E3MDgzOmFsaWNlIiwidmMiOnsiQGNvbnRleHQiOlsiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvdjEiLCJodHRwczovL3czaWQub3JnL3NlY3VyaXR5L3N1aXRlcy9qd3MtMjAyMC92MSIsImh0dHBzOi8vd3d3LnczLm9yZy9ucy9kaWQvdjEiLHsibXZkLWNyZWRlbnRpYWxzIjoiaHR0cHM6Ly93M2lkLm9yZy9tdmQvY3JlZGVudGlhbHMvIiwibWVtYmVyc2hpcCI6Im12ZC1jcmVkZW50aWFsczptZW1iZXJzaGlwIiwibWVtYmVyc2hpcFR5cGUiOiJtdmQtY3JlZGVudGlhbHM6bWVtYmVyc2hpcFR5cGUiLCJ3ZWJzaXRlIjoibXZkLWNyZWRlbnRpYWxzOndlYnNpdGUiLCJjb250YWN0IjoibXZkLWNyZWRlbnRpYWxzOmNvbnRhY3QiLCJzaW5jZSI6Im12ZC1jcmVkZW50aWFsczpzaW5jZSJ9XSwiaWQiOiJodHRwOi8vb3JnLnlvdXJkYXRhc3BhY2UuY29tL2NyZWRlbnRpYWxzLzIzNDciLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiTWVtYmVyc2hpcENyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOndlYjpkYXRhc3BhY2UtaXNzdWVyIiwiaXNzdWFuY2VEYXRlIjoiMjAyMy0wOC0xOFQwMDowMDowMFoiLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDp3ZWI6Y29uc3VtZXItaWRlbnRpdHlodWIlM0E3MDgzOmNvbnN1bWVyIiwibWVtYmVyc2hpcCI6eyJtZW1iZXJzaGlwVHlwZSI6IkZ1bGxNZW1iZXIiLCJ3ZWJzaXRlIjoid3d3LndoYXRldmVyLmNvbSIsImNvbnRhY3QiOiJmaXp6LmJ1enpAd2hhdGV2ZXIuY29tIiwic2luY2UiOiIyMDIzLTAxLTAxVDAwOjAwOjAwWiJ9fX0sImlhdCI6MTc2OTUxMTA3OH0.C13JgUg8c2PRdTdqThmmTG40FTrGQ5zp2MIdlgarboKBq4jZ7rZVX6Xg1_XMK50NRcnU0kIGL1xk1KQpan-QDA", "format": "VC1_0_JWT", "credential": { "credentialSubject": [ diff --git a/deployment/assets/credentials/k8s/provider/dataprocessor-credential.json b/deployment/assets/credentials/k8s/provider/dataprocessor-credential.json index 7ed5bee2c..581ac0d93 100644 --- a/deployment/assets/credentials/k8s/provider/dataprocessor-credential.json +++ b/deployment/assets/credentials/k8s/provider/dataprocessor-credential.json @@ -9,7 +9,7 @@ "reissuancePolicy": null, "verifiableCredential": { "format": "VC1_0_JWT", - "rawVc": "eyJraWQiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIja2V5LTEiLCJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJpc3MiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIiLCJhdWQiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkZW50aXR5aHViJTNBNzA4Mzpib2IiLCJzdWIiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkZW50aXR5aHViJTNBNzA4Mzpib2IiLCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vdzNpZC5vcmcvc2VjdXJpdHkvc3VpdGVzL2p3cy0yMDIwL3YxIiwiaHR0cHM6Ly93d3cudzMub3JnL25zL2RpZC92MSIseyJtdmQtY3JlZGVudGlhbHMiOiJodHRwczovL3czaWQub3JnL212ZC9jcmVkZW50aWFscy8iLCJjb250cmFjdFZlcnNpb24iOiJtdmQtY3JlZGVudGlhbHM6Y29udHJhY3RWZXJzaW9uIiwibGV2ZWwiOiJtdmQtY3JlZGVudGlhbHM6bGV2ZWwifV0sImlkIjoiaHR0cDovL29yZy55b3VyZGF0YXNwYWNlLmNvbS9jcmVkZW50aWFscy8yMzQ3IiwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIkRhdGFQcm9jZXNzb3JDcmVkZW50aWFsIl0sImlzc3VlciI6ImRpZDp3ZWI6ZGF0YXNwYWNlLWlzc3VlciIsImlzc3VhbmNlRGF0ZSI6IjIwMjMtMDgtMThUMDA6MDA6MDBaIiwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkZW50aXR5aHViJTNBNzA4Mzpwcm92aWRlciIsImxldmVsIjoicHJvY2Vzc2luZyIsImNvbnRyYWN0VmVyc2lvbiI6IjEuMC4wIn19LCJpYXQiOjE3NDg4NDQ5MTl9.lgSIzaPA9mm1LTEssDlfG2bcKUyhjWfjl85yEMHcKxAjl3kyFw1lBSokCR85f2bm-ZBHiAfCh9M9W1jixjPTCg", + "rawVc": "eyJraWQiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIja2V5LTEiLCJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJpc3MiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIiLCJhdWQiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkZW50aXR5aHViJTNBNzA4Mzpib2IiLCJzdWIiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkZW50aXR5aHViJTNBNzA4Mzpib2IiLCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vdzNpZC5vcmcvc2VjdXJpdHkvc3VpdGVzL2p3cy0yMDIwL3YxIiwiaHR0cHM6Ly93d3cudzMub3JnL25zL2RpZC92MSIseyJtdmQtY3JlZGVudGlhbHMiOiJodHRwczovL3czaWQub3JnL212ZC9jcmVkZW50aWFscy8iLCJjb250cmFjdFZlcnNpb24iOiJtdmQtY3JlZGVudGlhbHM6Y29udHJhY3RWZXJzaW9uIiwibGV2ZWwiOiJtdmQtY3JlZGVudGlhbHM6bGV2ZWwifV0sImlkIjoiaHR0cDovL29yZy55b3VyZGF0YXNwYWNlLmNvbS9jcmVkZW50aWFscy8yMzQ3IiwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIkRhdGFQcm9jZXNzb3JDcmVkZW50aWFsIl0sImlzc3VlciI6ImRpZDp3ZWI6ZGF0YXNwYWNlLWlzc3VlciIsImlzc3VhbmNlRGF0ZSI6IjIwMjMtMDgtMThUMDA6MDA6MDBaIiwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkZW50aXR5aHViJTNBNzA4Mzpwcm92aWRlciIsImxldmVsIjoicHJvY2Vzc2luZyIsImNvbnRyYWN0VmVyc2lvbiI6IjEuMC4wIn19LCJpYXQiOjE3Njk1MTEwNzh9.WfLbQ2hOGeIwlD-TFj-_mOUswjQsCYmH5l9GexWKqoPNatLw7wgMFCgQiXTUK2V_0VIbxk9NLP8eNEdTgLoqBw", "credential": { "credentialSubject": [ { diff --git a/deployment/assets/credentials/k8s/provider/membership-credential.json b/deployment/assets/credentials/k8s/provider/membership-credential.json index 076ef60e0..c587ebfe5 100644 --- a/deployment/assets/credentials/k8s/provider/membership-credential.json +++ b/deployment/assets/credentials/k8s/provider/membership-credential.json @@ -8,7 +8,7 @@ "issuancePolicy": null, "reissuancePolicy": null, "verifiableCredential": { - "rawVc": "eyJraWQiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIja2V5LTEiLCJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJpc3MiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIiLCJhdWQiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkZW50aXR5aHViJTNBNzA4Mzpib2IiLCJzdWIiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkZW50aXR5aHViJTNBNzA4Mzpib2IiLCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vdzNpZC5vcmcvc2VjdXJpdHkvc3VpdGVzL2p3cy0yMDIwL3YxIiwiaHR0cHM6Ly93d3cudzMub3JnL25zL2RpZC92MSIseyJtdmQtY3JlZGVudGlhbHMiOiJodHRwczovL3czaWQub3JnL212ZC9jcmVkZW50aWFscy8iLCJtZW1iZXJzaGlwIjoibXZkLWNyZWRlbnRpYWxzOm1lbWJlcnNoaXAiLCJtZW1iZXJzaGlwVHlwZSI6Im12ZC1jcmVkZW50aWFsczptZW1iZXJzaGlwVHlwZSIsIndlYnNpdGUiOiJtdmQtY3JlZGVudGlhbHM6d2Vic2l0ZSIsImNvbnRhY3QiOiJtdmQtY3JlZGVudGlhbHM6Y29udGFjdCIsInNpbmNlIjoibXZkLWNyZWRlbnRpYWxzOnNpbmNlIn1dLCJpZCI6Imh0dHA6Ly9vcmcueW91cmRhdGFzcGFjZS5jb20vY3JlZGVudGlhbHMvMjM0NyIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJNZW1iZXJzaGlwQ3JlZGVudGlhbCJdLCJpc3N1ZXIiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIiLCJpc3N1YW5jZURhdGUiOiIyMDIzLTA4LTE4VDAwOjAwOjAwWiIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOndlYjpwcm92aWRlci1pZGVudGl0eWh1YiUzQTcwODM6cHJvdmlkZXIiLCJtZW1iZXJzaGlwIjp7Im1lbWJlcnNoaXBUeXBlIjoiRnVsbE1lbWJlciIsIndlYnNpdGUiOiJ3d3cud2hhdGV2ZXIuY29tIiwiY29udGFjdCI6Im1peC5tYXhAd2hhdGV2ZXIuY29tIiwic2luY2UiOiIyMDIzLTAxLTAxVDAwOjAwOjAwWiJ9fX0sImlhdCI6MTc0ODg0NDkxOH0.iX84wIF6unwmOWPtyRHAYv-YaoDSTzHl1ioZcfa-Y6aMGzbgD4EDhjKY9syR5mdYYIvqs__cAN-d3MOKbMgjDA", + "rawVc": "eyJraWQiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIja2V5LTEiLCJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJpc3MiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIiLCJhdWQiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkZW50aXR5aHViJTNBNzA4Mzpib2IiLCJzdWIiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkZW50aXR5aHViJTNBNzA4Mzpib2IiLCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vdzNpZC5vcmcvc2VjdXJpdHkvc3VpdGVzL2p3cy0yMDIwL3YxIiwiaHR0cHM6Ly93d3cudzMub3JnL25zL2RpZC92MSIseyJtdmQtY3JlZGVudGlhbHMiOiJodHRwczovL3czaWQub3JnL212ZC9jcmVkZW50aWFscy8iLCJtZW1iZXJzaGlwIjoibXZkLWNyZWRlbnRpYWxzOm1lbWJlcnNoaXAiLCJtZW1iZXJzaGlwVHlwZSI6Im12ZC1jcmVkZW50aWFsczptZW1iZXJzaGlwVHlwZSIsIndlYnNpdGUiOiJtdmQtY3JlZGVudGlhbHM6d2Vic2l0ZSIsImNvbnRhY3QiOiJtdmQtY3JlZGVudGlhbHM6Y29udGFjdCIsInNpbmNlIjoibXZkLWNyZWRlbnRpYWxzOnNpbmNlIn1dLCJpZCI6Imh0dHA6Ly9vcmcueW91cmRhdGFzcGFjZS5jb20vY3JlZGVudGlhbHMvMjM0NyIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJNZW1iZXJzaGlwQ3JlZGVudGlhbCJdLCJpc3N1ZXIiOiJkaWQ6d2ViOmRhdGFzcGFjZS1pc3N1ZXIiLCJpc3N1YW5jZURhdGUiOiIyMDIzLTA4LTE4VDAwOjAwOjAwWiIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOndlYjpwcm92aWRlci1pZGVudGl0eWh1YiUzQTcwODM6cHJvdmlkZXIiLCJtZW1iZXJzaGlwIjp7Im1lbWJlcnNoaXBUeXBlIjoiRnVsbE1lbWJlciIsIndlYnNpdGUiOiJ3d3cud2hhdGV2ZXIuY29tIiwiY29udGFjdCI6Im1peC5tYXhAd2hhdGV2ZXIuY29tIiwic2luY2UiOiIyMDIzLTAxLTAxVDAwOjAwOjAwWiJ9fX0sImlhdCI6MTc2OTUxMTA3N30.ARHPRA0VhoYAC6oI1Ue0iFNcQtPZ48qS-St4ZY6Rx-njB1wUR9NzstcQ93CI2Yexjl9eR3qVflib6fEQWYrFBg", "format": "VC1_0_JWT", "credential": { "credentialSubject": [ diff --git a/deployment/assets/credentials/local/consumer/dataprocessor-credential.json b/deployment/assets/credentials/local/consumer/dataprocessor-credential.json index 934f2d850..094fefb54 100644 --- a/deployment/assets/credentials/local/consumer/dataprocessor-credential.json +++ b/deployment/assets/credentials/local/consumer/dataprocessor-credential.json @@ -9,7 +9,7 @@ "reissuancePolicy": null, "verifiableCredential": { "format": "VC1_0_JWT", - "rawVc": "eyJraWQiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYja2V5LTEiLCJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJpc3MiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYiLCJhdWQiOiJkaWQ6d2ViOmNvbnN1bWVyLWlkZW50aXR5aHViJTNBNzA4MzphbGljZSIsInN1YiI6ImRpZDp3ZWI6Y29uc3VtZXItaWRlbnRpdHlodWIlM0E3MDgzOmFsaWNlIiwidmMiOnsiQGNvbnRleHQiOlsiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvdjEiLCJodHRwczovL3czaWQub3JnL3NlY3VyaXR5L3N1aXRlcy9qd3MtMjAyMC92MSIsImh0dHBzOi8vd3d3LnczLm9yZy9ucy9kaWQvdjEiLHsibXZkLWNyZWRlbnRpYWxzIjoiaHR0cHM6Ly93M2lkLm9yZy9tdmQvY3JlZGVudGlhbHMvIiwiY29udHJhY3RWZXJzaW9uIjoibXZkLWNyZWRlbnRpYWxzOmNvbnRyYWN0VmVyc2lvbiIsImxldmVsIjoibXZkLWNyZWRlbnRpYWxzOmxldmVsIn1dLCJpZCI6Imh0dHA6Ly9vcmcueW91cmRhdGFzcGFjZS5jb20vY3JlZGVudGlhbHMvMjM0NyIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJEYXRhUHJvY2Vzc29yQ3JlZGVudGlhbCJdLCJpc3N1ZXIiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYiLCJpc3N1YW5jZURhdGUiOiIyMDIzLTA4LTE4VDAwOjAwOjAwWiIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOndlYjpsb2NhbGhvc3QlM0E3MDgzIiwiY29udHJhY3RWZXJzaW9uIjoiMS4wLjAiLCJsZXZlbCI6InByb2Nlc3NpbmcifX0sImlhdCI6MTc0ODg0NDkxOX0.B3ZjHNsiOhuiv78uv4hu08LyA9gZrciMhKOHsC9CV99_KesoWQAjrsg2bJd2b3QQguLoR0C3S3u-9tcYvmB1Cg", + "rawVc": "eyJraWQiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYja2V5LTEiLCJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJpc3MiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYiLCJhdWQiOiJkaWQ6d2ViOmNvbnN1bWVyLWlkZW50aXR5aHViJTNBNzA4MzphbGljZSIsInN1YiI6ImRpZDp3ZWI6Y29uc3VtZXItaWRlbnRpdHlodWIlM0E3MDgzOmFsaWNlIiwidmMiOnsiQGNvbnRleHQiOlsiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvdjEiLCJodHRwczovL3czaWQub3JnL3NlY3VyaXR5L3N1aXRlcy9qd3MtMjAyMC92MSIsImh0dHBzOi8vd3d3LnczLm9yZy9ucy9kaWQvdjEiLHsibXZkLWNyZWRlbnRpYWxzIjoiaHR0cHM6Ly93M2lkLm9yZy9tdmQvY3JlZGVudGlhbHMvIiwiY29udHJhY3RWZXJzaW9uIjoibXZkLWNyZWRlbnRpYWxzOmNvbnRyYWN0VmVyc2lvbiIsImxldmVsIjoibXZkLWNyZWRlbnRpYWxzOmxldmVsIn1dLCJpZCI6Imh0dHA6Ly9vcmcueW91cmRhdGFzcGFjZS5jb20vY3JlZGVudGlhbHMvMjM0NyIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJEYXRhUHJvY2Vzc29yQ3JlZGVudGlhbCJdLCJpc3N1ZXIiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYiLCJpc3N1YW5jZURhdGUiOiIyMDIzLTA4LTE4VDAwOjAwOjAwWiIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOndlYjpsb2NhbGhvc3QlM0E3MDgzIiwiY29udHJhY3RWZXJzaW9uIjoiMS4wLjAiLCJsZXZlbCI6InByb2Nlc3NpbmcifX0sImlhdCI6MTc2OTUxMTA3OH0.UDIGZ5izyeEcI3EK1nO_x0gLKbSiRGbZZYwcnlcCjANVH-rzGXeTJZ4NK1qpv8XHGMUh24sfAxwnhnzzI3kNBQ", "credential": { "credentialSubject": [ { diff --git a/deployment/assets/credentials/local/consumer/membership-credential.json b/deployment/assets/credentials/local/consumer/membership-credential.json index 95ce92cd9..63bd267e9 100644 --- a/deployment/assets/credentials/local/consumer/membership-credential.json +++ b/deployment/assets/credentials/local/consumer/membership-credential.json @@ -8,7 +8,7 @@ "issuancePolicy": null, "reissuancePolicy": null, "verifiableCredential": { - "rawVc": "eyJraWQiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYja2V5LTEiLCJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJpc3MiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYiLCJhdWQiOiJkaWQ6d2ViOmNvbnN1bWVyLWlkZW50aXR5aHViJTNBNzA4MzphbGljZSIsInN1YiI6ImRpZDp3ZWI6Y29uc3VtZXItaWRlbnRpdHlodWIlM0E3MDgzOmFsaWNlIiwidmMiOnsiQGNvbnRleHQiOlsiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvdjEiLCJodHRwczovL3czaWQub3JnL3NlY3VyaXR5L3N1aXRlcy9qd3MtMjAyMC92MSIsImh0dHBzOi8vd3d3LnczLm9yZy9ucy9kaWQvdjEiLHsibXZkLWNyZWRlbnRpYWxzIjoiaHR0cHM6Ly93M2lkLm9yZy9tdmQvY3JlZGVudGlhbHMvIiwibWVtYmVyc2hpcCI6Im12ZC1jcmVkZW50aWFsczptZW1iZXJzaGlwIiwibWVtYmVyc2hpcFR5cGUiOiJtdmQtY3JlZGVudGlhbHM6bWVtYmVyc2hpcFR5cGUiLCJ3ZWJzaXRlIjoibXZkLWNyZWRlbnRpYWxzOndlYnNpdGUiLCJjb250YWN0IjoibXZkLWNyZWRlbnRpYWxzOmNvbnRhY3QiLCJzaW5jZSI6Im12ZC1jcmVkZW50aWFsczpzaW5jZSJ9XSwiaWQiOiJodHRwOi8vb3JnLnlvdXJkYXRhc3BhY2UuY29tL2NyZWRlbnRpYWxzLzIzNDciLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiTWVtYmVyc2hpcENyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOndlYjpsb2NhbGhvc3QlM0E5ODc2IiwiaXNzdWFuY2VEYXRlIjoiMjAyMy0wOC0xOFQwMDowMDowMFoiLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDp3ZWI6bG9jYWxob3N0JTNBNzA4MyIsIm1lbWJlcnNoaXAiOnsibWVtYmVyc2hpcFR5cGUiOiJGdWxsTWVtYmVyIiwid2Vic2l0ZSI6Ind3dy53aGF0ZXZlci5jb20iLCJjb250YWN0IjoibWl4Lm1heEB3aGF0ZXZlci5jb20iLCJzaW5jZSI6IjIwMjMtMDEtMDFUMDA6MDA6MDBaIn19fSwiaWF0IjoxNzQ4ODQ0OTE5fQ.xnb1qnjEUpSAzFlJT9krVkW8y7MffVJL7xhfimLEV2ADYtRw_94LvcYuv-eFwMcOEMtNzfWj4MRoM2IslI5rBw", + "rawVc": "eyJraWQiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYja2V5LTEiLCJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJpc3MiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYiLCJhdWQiOiJkaWQ6d2ViOmNvbnN1bWVyLWlkZW50aXR5aHViJTNBNzA4MzphbGljZSIsInN1YiI6ImRpZDp3ZWI6Y29uc3VtZXItaWRlbnRpdHlodWIlM0E3MDgzOmFsaWNlIiwidmMiOnsiQGNvbnRleHQiOlsiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvdjEiLCJodHRwczovL3czaWQub3JnL3NlY3VyaXR5L3N1aXRlcy9qd3MtMjAyMC92MSIsImh0dHBzOi8vd3d3LnczLm9yZy9ucy9kaWQvdjEiLHsibXZkLWNyZWRlbnRpYWxzIjoiaHR0cHM6Ly93M2lkLm9yZy9tdmQvY3JlZGVudGlhbHMvIiwibWVtYmVyc2hpcCI6Im12ZC1jcmVkZW50aWFsczptZW1iZXJzaGlwIiwibWVtYmVyc2hpcFR5cGUiOiJtdmQtY3JlZGVudGlhbHM6bWVtYmVyc2hpcFR5cGUiLCJ3ZWJzaXRlIjoibXZkLWNyZWRlbnRpYWxzOndlYnNpdGUiLCJjb250YWN0IjoibXZkLWNyZWRlbnRpYWxzOmNvbnRhY3QiLCJzaW5jZSI6Im12ZC1jcmVkZW50aWFsczpzaW5jZSJ9XSwiaWQiOiJodHRwOi8vb3JnLnlvdXJkYXRhc3BhY2UuY29tL2NyZWRlbnRpYWxzLzIzNDciLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiTWVtYmVyc2hpcENyZWRlbnRpYWwiXSwiaXNzdWVyIjoiZGlkOndlYjpsb2NhbGhvc3QlM0E5ODc2IiwiaXNzdWFuY2VEYXRlIjoiMjAyMy0wOC0xOFQwMDowMDowMFoiLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDp3ZWI6bG9jYWxob3N0JTNBNzA4MyIsIm1lbWJlcnNoaXAiOnsibWVtYmVyc2hpcFR5cGUiOiJGdWxsTWVtYmVyIiwid2Vic2l0ZSI6Ind3dy53aGF0ZXZlci5jb20iLCJjb250YWN0IjoibWl4Lm1heEB3aGF0ZXZlci5jb20iLCJzaW5jZSI6IjIwMjMtMDEtMDFUMDA6MDA6MDBaIn19fSwiaWF0IjoxNzY5NTExMDc4fQ.c-4O4pzWedCYzYl4kk5NfdkQGZROA53KyzqtU7LucF5AnCg8ESUHJqp9m8ZHqO51JLdF6IJV7dk4mJhwrDQXCQ", "format": "VC1_0_JWT", "credential": { "credentialSubject": [ diff --git a/deployment/assets/credentials/local/provider/dataprocessor-credential.json b/deployment/assets/credentials/local/provider/dataprocessor-credential.json index aadbef8fe..5e448ddc9 100644 --- a/deployment/assets/credentials/local/provider/dataprocessor-credential.json +++ b/deployment/assets/credentials/local/provider/dataprocessor-credential.json @@ -9,7 +9,7 @@ "reissuancePolicy": null, "verifiableCredential": { "format": "VC1_0_JWT", - "rawVc": "eyJraWQiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYja2V5LTEiLCJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJpc3MiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYiLCJhdWQiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkZW50aXR5aHViJTNBNzA4Mzpib2IiLCJzdWIiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkZW50aXR5aHViJTNBNzA4Mzpib2IiLCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vdzNpZC5vcmcvc2VjdXJpdHkvc3VpdGVzL2p3cy0yMDIwL3YxIiwiaHR0cHM6Ly93d3cudzMub3JnL25zL2RpZC92MSIseyJtdmQtY3JlZGVudGlhbHMiOiJodHRwczovL3czaWQub3JnL212ZC9jcmVkZW50aWFscy8iLCJjb250cmFjdFZlcnNpb24iOiJtdmQtY3JlZGVudGlhbHM6Y29udHJhY3RWZXJzaW9uIiwibGV2ZWwiOiJtdmQtY3JlZGVudGlhbHM6bGV2ZWwifV0sImlkIjoiaHR0cDovL29yZy55b3VyZGF0YXNwYWNlLmNvbS9jcmVkZW50aWFscy8yMzQ3IiwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIkRhdGFQcm9jZXNzb3JDcmVkZW50aWFsIl0sImlzc3VlciI6ImRpZDp3ZWI6bG9jYWxob3N0JTNBOTg3NiIsImlzc3VhbmNlRGF0ZSI6IjIwMjMtMDgtMThUMDA6MDA6MDBaIiwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTcwOTMiLCJsZXZlbCI6InByb2Nlc3NpbmciLCJjb250cmFjdFZlcnNpb24iOiIxLjAuMCJ9fSwiaWF0IjoxNzQ4ODQ0OTE5fQ.aeb2uwwwEbaa3236XJhNOpJ_KxUIIefYeheAiw7OPtk_rXjmFOQ_aa7F09kEEgGK1NB3sijfVIEo5E96vMfZCQ", + "rawVc": "eyJraWQiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYja2V5LTEiLCJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJpc3MiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYiLCJhdWQiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkZW50aXR5aHViJTNBNzA4Mzpib2IiLCJzdWIiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkZW50aXR5aHViJTNBNzA4Mzpib2IiLCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vdzNpZC5vcmcvc2VjdXJpdHkvc3VpdGVzL2p3cy0yMDIwL3YxIiwiaHR0cHM6Ly93d3cudzMub3JnL25zL2RpZC92MSIseyJtdmQtY3JlZGVudGlhbHMiOiJodHRwczovL3czaWQub3JnL212ZC9jcmVkZW50aWFscy8iLCJjb250cmFjdFZlcnNpb24iOiJtdmQtY3JlZGVudGlhbHM6Y29udHJhY3RWZXJzaW9uIiwibGV2ZWwiOiJtdmQtY3JlZGVudGlhbHM6bGV2ZWwifV0sImlkIjoiaHR0cDovL29yZy55b3VyZGF0YXNwYWNlLmNvbS9jcmVkZW50aWFscy8yMzQ3IiwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIkRhdGFQcm9jZXNzb3JDcmVkZW50aWFsIl0sImlzc3VlciI6ImRpZDp3ZWI6bG9jYWxob3N0JTNBOTg3NiIsImlzc3VhbmNlRGF0ZSI6IjIwMjMtMDgtMThUMDA6MDA6MDBaIiwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTcwOTMiLCJsZXZlbCI6InByb2Nlc3NpbmciLCJjb250cmFjdFZlcnNpb24iOiIxLjAuMCJ9fSwiaWF0IjoxNzY5NTExMDc4fQ.qqxdAG6lT_Eiwvae788Vo2fhjswBdTxSwsYKeHKFMnfnQwshdld-vh4vQyOvT_f8_e_tbzHRr-OAVyHxpSFABg", "credential": { "credentialSubject": [ { diff --git a/deployment/assets/credentials/local/provider/membership-credential.json b/deployment/assets/credentials/local/provider/membership-credential.json index 419beea63..eb899c197 100644 --- a/deployment/assets/credentials/local/provider/membership-credential.json +++ b/deployment/assets/credentials/local/provider/membership-credential.json @@ -8,7 +8,7 @@ "issuancePolicy": null, "reissuancePolicy": null, "verifiableCredential": { - "rawVc": "eyJraWQiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYja2V5LTEiLCJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJpc3MiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYiLCJhdWQiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkZW50aXR5aHViJTNBNzA4Mzpib2IiLCJzdWIiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkZW50aXR5aHViJTNBNzA4Mzpib2IiLCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vdzNpZC5vcmcvc2VjdXJpdHkvc3VpdGVzL2p3cy0yMDIwL3YxIiwiaHR0cHM6Ly93d3cudzMub3JnL25zL2RpZC92MSIseyJtdmQtY3JlZGVudGlhbHMiOiJodHRwczovL3czaWQub3JnL212ZC9jcmVkZW50aWFscy8iLCJtZW1iZXJzaGlwIjoibXZkLWNyZWRlbnRpYWxzOm1lbWJlcnNoaXAiLCJtZW1iZXJzaGlwVHlwZSI6Im12ZC1jcmVkZW50aWFsczptZW1iZXJzaGlwVHlwZSIsIndlYnNpdGUiOiJtdmQtY3JlZGVudGlhbHM6d2Vic2l0ZSIsImNvbnRhY3QiOiJtdmQtY3JlZGVudGlhbHM6Y29udGFjdCIsInNpbmNlIjoibXZkLWNyZWRlbnRpYWxzOnNpbmNlIn1dLCJpZCI6Imh0dHA6Ly9vcmcueW91cmRhdGFzcGFjZS5jb20vY3JlZGVudGlhbHMvMTIzNCIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJNZW1iZXJzaGlwQ3JlZGVudGlhbCJdLCJpc3N1ZXIiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYiLCJpc3N1YW5jZURhdGUiOiIyMDIzLTA4LTE4VDAwOjAwOjAwWiIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOndlYjpsb2NhbGhvc3QlM0E3MDkzIiwibWVtYmVyc2hpcCI6eyJtZW1iZXJzaGlwVHlwZSI6IlByb3NwZWN0TWVtYmVyIiwid2Vic2l0ZSI6Ind3dy5xdWl6enF1YXp6LmNvbSIsImNvbnRhY3QiOiJmb28uYmFyQHF1aXp6cXVhenouY29tIiwic2luY2UiOiIyMDIzLTAxLTAxVDAwOjAwOjAwWiJ9fX0sImlhdCI6MTc0ODg0NDkxOX0.HmC6-GC6GalGL6n8UQ2BNDOAS1qNJ0B6A7gObM_p0psOkZqCvtSQ-gwMTX8qd5gK7eihGuAEiMQ7Z_gCvgKKAw", + "rawVc": "eyJraWQiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYja2V5LTEiLCJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJpc3MiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYiLCJhdWQiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkZW50aXR5aHViJTNBNzA4Mzpib2IiLCJzdWIiOiJkaWQ6d2ViOnByb3ZpZGVyLWlkZW50aXR5aHViJTNBNzA4Mzpib2IiLCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vdzNpZC5vcmcvc2VjdXJpdHkvc3VpdGVzL2p3cy0yMDIwL3YxIiwiaHR0cHM6Ly93d3cudzMub3JnL25zL2RpZC92MSIseyJtdmQtY3JlZGVudGlhbHMiOiJodHRwczovL3czaWQub3JnL212ZC9jcmVkZW50aWFscy8iLCJtZW1iZXJzaGlwIjoibXZkLWNyZWRlbnRpYWxzOm1lbWJlcnNoaXAiLCJtZW1iZXJzaGlwVHlwZSI6Im12ZC1jcmVkZW50aWFsczptZW1iZXJzaGlwVHlwZSIsIndlYnNpdGUiOiJtdmQtY3JlZGVudGlhbHM6d2Vic2l0ZSIsImNvbnRhY3QiOiJtdmQtY3JlZGVudGlhbHM6Y29udGFjdCIsInNpbmNlIjoibXZkLWNyZWRlbnRpYWxzOnNpbmNlIn1dLCJpZCI6Imh0dHA6Ly9vcmcueW91cmRhdGFzcGFjZS5jb20vY3JlZGVudGlhbHMvMTIzNCIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJNZW1iZXJzaGlwQ3JlZGVudGlhbCJdLCJpc3N1ZXIiOiJkaWQ6d2ViOmxvY2FsaG9zdCUzQTk4NzYiLCJpc3N1YW5jZURhdGUiOiIyMDIzLTA4LTE4VDAwOjAwOjAwWiIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOndlYjpsb2NhbGhvc3QlM0E3MDkzIiwibWVtYmVyc2hpcCI6eyJtZW1iZXJzaGlwVHlwZSI6IlByb3NwZWN0TWVtYmVyIiwid2Vic2l0ZSI6Ind3dy5xdWl6enF1YXp6LmNvbSIsImNvbnRhY3QiOiJmb28uYmFyQHF1aXp6cXVhenouY29tIiwic2luY2UiOiIyMDIzLTAxLTAxVDAwOjAwOjAwWiJ9fX0sImlhdCI6MTc2OTUxMTA3OH0.Q3FfHKNGwtSCkrfnybWm6Uu9jqGysfE5YBlWoXLkYRdUTQDT31LrUk5Uz6ae2JbqaZiSsptp_iRappeuBG67CQ", "format": "VC1_0_JWT", "credential": { "credentialSubject": [ diff --git a/deployment/assets/issuer/did.docker.json b/deployment/assets/issuer/did.docker.json index 1c819d142..8fa1b9707 100644 --- a/deployment/assets/issuer/did.docker.json +++ b/deployment/assets/issuer/did.docker.json @@ -1,26 +1 @@ -{ - "service": [], - "verificationMethod": [ - { - "id": "did:web:localhost%3A9876#key-1", - "type": "JsonWebKey2020", - "controller": "did:web:localhost%3A9876", - "publicKeyMultibase": null, - "publicKeyJwk": { - "kty": "OKP", - "crv": "Ed25519", - "x": "Hsq2QXPbbsU7j6JwXstbpxGSgliI04g_fU3z2nwkuVc" - } - } - ], - "authentication": [ - "key-1" - ], - "id": "did:web:localhost%3A9876", - "@context": [ - "https://www.w3.org/ns/did/v1", - { - "@base": "did:web:localhost%3A9876" - } - ] -} \ No newline at end of file +{"service":[],"verificationMethod":[{"id":"did:web:localhost%3A9876#key-1","type":"JsonWebKey2020","controller":"did:web:localhost%3A9876","publicKeyMultibase":null,"publicKeyJwk":{"kty":"OKP","crv":"Ed25519","x":"Hsq2QXPbbsU7j6JwXstbpxGSgliI04g_fU3z2nwkuVc"}}],"authentication":["key-1"],"id":"did:web:localhost%3A9876","@context":["https://www.w3.org/ns/did/v1",{"@base":"did:web:localhost%3A9876"}]} \ No newline at end of file diff --git a/deployment/assets/issuer/did.k8s.json b/deployment/assets/issuer/did.k8s.json index b6b0d01dc..87759dcbf 100644 --- a/deployment/assets/issuer/did.k8s.json +++ b/deployment/assets/issuer/did.k8s.json @@ -1,26 +1 @@ -{ - "service": [], - "verificationMethod": [ - { - "id": "did:web:dataspace-issuer#key-1", - "type": "JsonWebKey2020", - "controller": "did:web:dataspace-issuer", - "publicKeyMultibase": null, - "publicKeyJwk": { - "kty": "OKP", - "crv": "Ed25519", - "x": "Hsq2QXPbbsU7j6JwXstbpxGSgliI04g_fU3z2nwkuVc" - } - } - ], - "authentication": [ - "key-1" - ], - "id": "did:web:dataspace-issuer", - "@context": [ - "https://www.w3.org/ns/did/v1", - { - "@base": "did:web:dataspace-issuer" - } - ] -} \ No newline at end of file +{"service":[],"verificationMethod":[{"id":"did:web:dataspace-issuer#key-1","type":"JsonWebKey2020","controller":"did:web:dataspace-issuer","publicKeyMultibase":null,"publicKeyJwk":{"kty":"OKP","crv":"Ed25519","x":"Hsq2QXPbbsU7j6JwXstbpxGSgliI04g_fU3z2nwkuVc"}}],"authentication":["key-1"],"id":"did:web:dataspace-issuer","@context":["https://www.w3.org/ns/did/v1",{"@base":"did:web:dataspace-issuer"}]} \ No newline at end of file diff --git a/deployment/consumer.tf b/deployment/consumer.tf index 2e194b89d..33e21b104 100644 --- a/deployment/consumer.tf +++ b/deployment/consumer.tf @@ -25,7 +25,7 @@ module "consumer-connector" { url = "jdbc:postgresql://${module.consumer-postgres.database-url}/consumer" } vault-url = "http://consumer-vault:8200" - namespace = kubernetes_namespace.ns.metadata.0.name + namespace = "consumer" #kubernetes_namespace.ns.metadata.0.name sts-token-url = "${module.consumer-identityhub.sts-token-url}/token" useSVE = var.useSVE } @@ -44,7 +44,7 @@ module "consumer-identityhub" { password = "consumer" url = "jdbc:postgresql://${module.consumer-postgres.database-url}/consumer" } - namespace = kubernetes_namespace.ns.metadata.0.name + namespace = "consumer" #kubernetes_namespace.ns.metadata.0.name useSVE = var.useSVE } @@ -53,7 +53,7 @@ module "consumer-identityhub" { module "consumer-vault" { source = "./modules/vault" humanReadableName = "consumer-vault" - namespace = kubernetes_namespace.ns.metadata.0.name + namespace = "consumer" #kubernetes_namespace.ns.metadata.0.name } # Postgres database for the consumer @@ -62,14 +62,14 @@ module "consumer-postgres" { source = "./modules/postgres" instance-name = "consumer" init-sql-configs = ["consumer-initdb-config"] - namespace = kubernetes_namespace.ns.metadata.0.name + namespace = "consumer" #kubernetes_namespace.ns.metadata.0.name } # DB initialization for the EDC database resource "kubernetes_config_map" "postgres-initdb-config-consumer" { metadata { name = "consumer-initdb-config" - namespace = kubernetes_namespace.ns.metadata.0.name + namespace = "consumer" #kubernetes_namespace.ns.metadata.0.name } data = { "consumer-initdb-config.sql" = <<-EOT diff --git a/deployment/issuer.tf b/deployment/issuer.tf index c49f658f3..7420a1ab0 100644 --- a/deployment/issuer.tf +++ b/deployment/issuer.tf @@ -20,8 +20,8 @@ module "dataspace-issuer" { password = "issuer" url = "jdbc:postgresql://${module.dataspace-issuer-postgres.database-url}/issuer" } - vault-url = "http://consumer-vault:8200" - namespace = kubernetes_namespace.ns.metadata.0.name + vault-url = "http://consumer-vault.consumer.svc.cluster.local:8200" + namespace = "kordat" #kubernetes_namespace.ns.metadata.0.name useSVE = var.useSVE } @@ -31,14 +31,14 @@ module "dataspace-issuer-postgres" { source = "./modules/postgres" instance-name = "issuer" init-sql-configs = ["issuer-initdb-config"] - namespace = kubernetes_namespace.ns.metadata.0.name + namespace = "kordat" #kubernetes_namespace.ns.metadata.0.name } # DB initialization for the EDC database resource "kubernetes_config_map" "issuer-initdb-config" { metadata { name = "issuer-initdb-config" - namespace = kubernetes_namespace.ns.metadata.0.name + namespace = "kordat" #kubernetes_namespace.ns.metadata.0.name } data = { "issuer-initdb-config.sql" = <<-EOT diff --git a/deployment/issuer_nginx.tf b/deployment/issuer_nginx.tf index 3d6070a69..2ad00e466 100644 --- a/deployment/issuer_nginx.tf +++ b/deployment/issuer_nginx.tf @@ -21,7 +21,7 @@ resource "kubernetes_deployment" "dataspace-issuer-did-server" { metadata { name = "dataspace-issuer-server" - namespace = kubernetes_namespace.ns.metadata.0.name + namespace = "kordat" #kubernetes_namespace.ns.metadata.0.name labels = { App = "dataspace-issuer-server" } @@ -82,7 +82,7 @@ resource "kubernetes_deployment" "dataspace-issuer-did-server" { resource "kubernetes_service" "dataspace-issuer-did-server-service" { metadata { name = "dataspace-issuer" # this must correlate with the Issuer's DID: did:web:dataspace-issuer -> http://dataspace-issuer/.well-known/did.json - namespace = kubernetes_namespace.ns.metadata.0.name + namespace = "kordat" #kubernetes_namespace.ns.metadata.0.name } spec { type = "NodePort" @@ -100,7 +100,7 @@ resource "kubernetes_service" "dataspace-issuer-did-server-service" { resource "kubernetes_config_map" "nginx-map" { metadata { name = "nginx-conf" - namespace = kubernetes_namespace.ns.metadata.0.name + namespace = "kordat" #kubernetes_namespace.ns.metadata.0.name } data = { diff --git a/deployment/modules/catalog-server/catalog-server.tf b/deployment/modules/catalog-server/catalog-server.tf index aad588755..cdd18a4f2 100644 --- a/deployment/modules/catalog-server/catalog-server.tf +++ b/deployment/modules/catalog-server/catalog-server.tf @@ -44,8 +44,8 @@ resource "kubernetes_deployment" "connector" { spec { container { name = lower(var.humanReadableName) - image = "catalog-server:latest" - image_pull_policy = "Never" + image = "150073872684.dkr.ecr.eu-west-1.amazonaws.com/kordat-dev-catalog-server:latest" + image_pull_policy = "IfNotPresent" env_from { config_map_ref { diff --git a/deployment/modules/connector/controlplane.tf b/deployment/modules/connector/controlplane.tf index 86b7722b2..68ed49597 100644 --- a/deployment/modules/connector/controlplane.tf +++ b/deployment/modules/connector/controlplane.tf @@ -44,8 +44,8 @@ resource "kubernetes_deployment" "controlplane" { spec { container { name = "connector-${lower(var.humanReadableName)}" - image = "controlplane:latest" - image_pull_policy = "Never" + image = "150073872684.dkr.ecr.eu-west-1.amazonaws.com/kordat-dev-controlplane:latest" + image_pull_policy = "IfNotPresent" env_from { config_map_ref { diff --git a/deployment/modules/connector/dataplane.tf b/deployment/modules/connector/dataplane.tf index 6a7d56e37..cfeadabd2 100644 --- a/deployment/modules/connector/dataplane.tf +++ b/deployment/modules/connector/dataplane.tf @@ -46,8 +46,8 @@ resource "kubernetes_deployment" "dataplane" { spec { container { name = "dataplane-${lower(var.humanReadableName)}" - image = "dataplane:latest" - image_pull_policy = "Never" + image = "150073872684.dkr.ecr.eu-west-1.amazonaws.com/kordat-dev-dataplane:latest" + image_pull_policy = "IfNotPresent" env_from { config_map_ref { diff --git a/deployment/modules/identity-hub/main.tf b/deployment/modules/identity-hub/main.tf index e8aacd8f9..d909d3300 100644 --- a/deployment/modules/identity-hub/main.tf +++ b/deployment/modules/identity-hub/main.tf @@ -37,8 +37,8 @@ resource "kubernetes_deployment" "identityhub" { spec { container { - image_pull_policy = "Never" - image = "identity-hub:latest" + image_pull_policy = "IfNotPresent" + image = "150073872684.dkr.ecr.eu-west-1.amazonaws.com/kordat-dev-identity-hub:latest" name = "identity-hub" env_from { diff --git a/deployment/modules/issuer/main.tf b/deployment/modules/issuer/main.tf index c19adf7e0..9a2e4efb7 100644 --- a/deployment/modules/issuer/main.tf +++ b/deployment/modules/issuer/main.tf @@ -37,8 +37,8 @@ resource "kubernetes_deployment" "issuerservice" { spec { container { - image_pull_policy = "Never" - image = "issuerservice:latest" + image_pull_policy = "IfNotPresent" + image = "150073872684.dkr.ecr.eu-west-1.amazonaws.com/kordat-dev-issuerservice:latest" name = "issuerservice" env_from { diff --git a/deployment/modules/postgres/main.tf b/deployment/modules/postgres/main.tf index 31571f954..4653df163 100644 --- a/deployment/modules/postgres/main.tf +++ b/deployment/modules/postgres/main.tf @@ -125,7 +125,7 @@ resource "kubernetes_service" "pg-service" { locals { app-name = "${var.instance-name}-postgres" - pg-image = "postgres:16.3-alpine3.20" + pg-image = "150073872684.dkr.ecr.eu-west-1.amazonaws.com/kordat-dev-postgres:16.3-alpine3.20" db-ip = kubernetes_service.pg-service.spec.0.cluster_ip db-url = "${kubernetes_service.pg-service.metadata[0].name}:${var.database-port}" } diff --git a/deployment/namespace.tf b/deployment/namespace.tf new file mode 100644 index 000000000..f1b9e1f8a --- /dev/null +++ b/deployment/namespace.tf @@ -0,0 +1,11 @@ +resource "kubernetes_namespace" "ns_consumer" { + metadata { + name = "consumer" + } +} + +resource "kubernetes_namespace" "ns_provider" { + metadata { + name = "provider" + } +} \ No newline at end of file diff --git a/deployment/provider.tf b/deployment/provider.tf index 454fa76ff..70744ced1 100644 --- a/deployment/provider.tf +++ b/deployment/provider.tf @@ -25,7 +25,7 @@ module "provider-qna-connector" { password = "provider-qna" url = "jdbc:postgresql://${module.provider-postgres.database-url}/provider_qna" } - namespace = kubernetes_namespace.ns.metadata.0.name + namespace = "provider" #kubernetes_namespace.ns.metadata.0.name vault-url = "http://provider-vault:8200" sts-token-url = "${module.provider-identityhub.sts-token-url}/token" useSVE = var.useSVE @@ -41,7 +41,7 @@ module "provider-manufacturing-connector" { password = "provider-manufacturing" url = "jdbc:postgresql://${module.provider-postgres.database-url}/provider_manufacturing" } - namespace = kubernetes_namespace.ns.metadata.0.name + namespace = "provider" #kubernetes_namespace.ns.metadata.0.name vault-url = "http://provider-vault:8200" sts-token-url = "${module.provider-identityhub.sts-token-url}/token" useSVE = var.useSVE @@ -56,7 +56,7 @@ module "provider-identityhub" { participantId = var.provider-did vault-url = "http://provider-vault:8200" service-name = "provider" - namespace = kubernetes_namespace.ns.metadata.0.name + namespace = "provider" #kubernetes_namespace.ns.metadata.0.name database = { user = "identity" @@ -71,7 +71,7 @@ module "provider-catalog-server" { source = "./modules/catalog-server" humanReadableName = "provider-catalog-server" participantId = var.provider-did - namespace = kubernetes_namespace.ns.metadata.0.name + namespace = "provider" #kubernetes_namespace.ns.metadata.0.name vault-url = "http://provider-vault:8200" sts-token-url = "${module.provider-identityhub.sts-token-url}/token" @@ -86,7 +86,7 @@ module "provider-catalog-server" { module "provider-vault" { source = "./modules/vault" humanReadableName = "provider-vault" - namespace = kubernetes_namespace.ns.metadata.0.name + namespace = "provider" #kubernetes_namespace.ns.metadata.0.name } # Postgres database for the consumer @@ -100,13 +100,13 @@ module "provider-postgres" { kubernetes_config_map.postgres-initdb-config-pm.metadata[0].name, kubernetes_config_map.postgres-initdb-config-ih.metadata[0].name, ] - namespace = kubernetes_namespace.ns.metadata.0.name + namespace = "provider" #kubernetes_namespace.ns.metadata.0.name } resource "kubernetes_config_map" "postgres-initdb-config-cs" { metadata { name = "cs-initdb-config" - namespace = kubernetes_namespace.ns.metadata.0.name + namespace = "provider" #kubernetes_namespace.ns.metadata.0.name } data = { "cs-initdb-config.sql" = <<-EOT @@ -121,7 +121,7 @@ resource "kubernetes_config_map" "postgres-initdb-config-cs" { resource "kubernetes_config_map" "postgres-initdb-config-pqna" { metadata { name = "provider-qna-initdb-config" - namespace = kubernetes_namespace.ns.metadata.0.name + namespace = "provider" #kubernetes_namespace.ns.metadata.0.name } data = { "provider-qna-initdb-config.sql" = <<-EOT @@ -136,7 +136,7 @@ resource "kubernetes_config_map" "postgres-initdb-config-pqna" { resource "kubernetes_config_map" "postgres-initdb-config-pm" { metadata { name = "provider-manufacturing-initdb-config" - namespace = kubernetes_namespace.ns.metadata.0.name + namespace = "provider" #kubernetes_namespace.ns.metadata.0.name } data = { "provider-manufacturing-initdb-config.sql" = <<-EOT @@ -151,7 +151,7 @@ resource "kubernetes_config_map" "postgres-initdb-config-pm" { resource "kubernetes_config_map" "postgres-initdb-config-ih" { metadata { name = "ih-initdb-config" - namespace = kubernetes_namespace.ns.metadata.0.name + namespace = "provider" #kubernetes_namespace.ns.metadata.0.name } data = { "ih-initdb-config.sql" = <<-EOT diff --git a/deployment/main.tf b/deployment/providers.tf similarity index 84% rename from deployment/main.tf rename to deployment/providers.tf index 2a96bac99..1eda6f3a1 100644 --- a/deployment/main.tf +++ b/deployment/providers.tf @@ -23,7 +23,6 @@ terraform { random = { source = "hashicorp/random" } - kubernetes = { source = "hashicorp/kubernetes" } @@ -32,6 +31,15 @@ terraform { source = "hashicorp/helm" } } + + backend "s3" { + region = "eu-west-1" + bucket = "aie-kordat-dev-terraform-remote-state" + key = "infra/kordat/mvd/terraform.tfstate" + profile = "kordat-dev" + } + + required_version = ">= 1.13.0" } provider "kubernetes" { @@ -43,9 +51,3 @@ provider "helm" { config_path = "~/.kube/config" } } - -resource "kubernetes_namespace" "ns" { - metadata { - name = "mvd" - } -} diff --git a/extensions/catalog-node-resolver/src/main/java/org/eclipse/edc/demo/participants/ParticipantsResolverExtension.java b/extensions/catalog-node-resolver/src/main/java/org/eclipse/edc/demo/participants/ParticipantsResolverExtension.java deleted file mode 100644 index c31ec3918..000000000 --- a/extensions/catalog-node-resolver/src/main/java/org/eclipse/edc/demo/participants/ParticipantsResolverExtension.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2024 Metaform Systems, Inc. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License, Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0 - * - * SPDX-License-Identifier: Apache-2.0 - * - * Contributors: - * Metaform Systems, Inc. - initial API and implementation - * - */ - -package org.eclipse.edc.demo.participants; - -import org.eclipse.edc.crawler.spi.TargetNodeDirectory; -import org.eclipse.edc.crawler.spi.TargetNodeFilter; -import org.eclipse.edc.demo.participants.resolver.LazyLoadNodeDirectory; -import org.eclipse.edc.iam.did.spi.resolution.DidResolverRegistry; -import org.eclipse.edc.runtime.metamodel.annotation.Extension; -import org.eclipse.edc.runtime.metamodel.annotation.Inject; -import org.eclipse.edc.runtime.metamodel.annotation.Provider; -import org.eclipse.edc.spi.monitor.Monitor; -import org.eclipse.edc.spi.system.ServiceExtension; -import org.eclipse.edc.spi.system.ServiceExtensionContext; -import org.eclipse.edc.spi.types.TypeManager; - -import java.io.File; - -import static org.eclipse.edc.demo.participants.ParticipantsResolverExtension.NAME; - -@Extension(value = NAME) -public class ParticipantsResolverExtension implements ServiceExtension { - public static final String NAME = "MVD Participant Resolver Extension"; - - public static final String PARTICIPANT_LIST_FILE_PATH = "edc.mvd.participants.list.file"; - - @Inject - private TypeManager typeManager; - - @Inject - private DidResolverRegistry didResolverRegistry; - - private File participantListFile; - private Monitor monitor; - private TargetNodeDirectory nodeDirectory; - - @Override - public String name() { - return NAME; - } - - @Override - public void initialize(ServiceExtensionContext context) { - var participantsPath = context.getConfig().getString(PARTICIPANT_LIST_FILE_PATH); - monitor = context.getMonitor().withPrefix("DEMO"); - - participantListFile = new File(participantsPath).getAbsoluteFile(); - if (!participantListFile.exists()) { - monitor.warning("Path '%s' does not exist. It must be a resolvable path with read access. Will not add any VCs.".formatted(participantsPath)); - } - } - - @Provider - public TargetNodeDirectory createLazyTargetNodeDirectory() { - if (nodeDirectory == null) { - nodeDirectory = new LazyLoadNodeDirectory(typeManager.getMapper(), participantListFile, didResolverRegistry, monitor); - } - return nodeDirectory; - } - - @Provider - public TargetNodeFilter skipSelfNodeFilter(ServiceExtensionContext context) { - return targetNode -> { - var predicateTest = !targetNode.id().equals(context.getParticipantId()); - if (!predicateTest) { - monitor.debug("Node filter: skipping node '%s' for participant '%s'".formatted(targetNode.id(), context.getParticipantId())); - } - return predicateTest; - }; - } - - -} diff --git a/extensions/catalog-node-resolver/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension b/extensions/catalog-node-resolver/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension index 9b6064c26..8a1808ca0 100644 --- a/extensions/catalog-node-resolver/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension +++ b/extensions/catalog-node-resolver/src/main/resources/META-INF/services/org.eclipse.edc.spi.system.ServiceExtension @@ -12,4 +12,4 @@ # # -org.eclipse.edc.demo.participants.ParticipantsResolverExtension \ No newline at end of file +# ParticipantsResolverExtension removed: participants are managed by kordat project, no federated catalog used \ No newline at end of file diff --git a/extensions/dcp-impl/src/main/java/org/eclipse/edc/demo/dcp/policy/AssignedParticipantConstraintFunction.java b/extensions/dcp-impl/src/main/java/org/eclipse/edc/demo/dcp/policy/AssignedParticipantConstraintFunction.java new file mode 100644 index 000000000..308c52571 --- /dev/null +++ b/extensions/dcp-impl/src/main/java/org/eclipse/edc/demo/dcp/policy/AssignedParticipantConstraintFunction.java @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2025 MinimumViableDataspace Contributors + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * MinimumViableDataspace Contributors - initial API and implementation + * + */ + +package org.eclipse.edc.demo.dcp.policy; + +import org.eclipse.edc.participant.spi.ParticipantAgentPolicyContext; +import org.eclipse.edc.policy.engine.spi.AtomicConstraintRuleFunction; +import org.eclipse.edc.policy.model.Operator; +import org.eclipse.edc.policy.model.Permission; + +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * Constraint function que valida que el participante que intenta acceder + * sea el participante asignado en la política. + * + * Esta función permite crear políticas donde solo ciertos participantes + * específicos pueden ver y negociar contratos para un asset. + * + * Ejemplo de uso en política con un solo participante asignado: + * + * { + * "leftOperand": "AssignedParticipant", + * "operator": "eq", + * "rightOperand": "did:web:consumer-identityhub%3A7083:consumer" + * } + * + * + * Ejemplo con múltiples participantes asignados: + * + * { + * "leftOperand": "AssignedParticipant", + * "operator": "isAnyOf", + * "rightOperand": "did:web:consumer1-identityhub%3A7083:consumer1,did:web:consumer2-identityhub%3A7083:consumer2" + * } + * + * + * Ejemplo de blacklist (todos excepto estos): + * + * { + * "leftOperand": "AssignedParticipant", + * "operator": "isNoneOf", + * "rightOperand": "ddid:web:consumer-identityhub%3A7083:consumer" + * } + * + */ + +public class AssignedParticipantConstraintFunction + implements AtomicConstraintRuleFunction { + + public static final String ASSIGNED_PARTICIPANT_KEY = "AssignedParticipant"; + + private AssignedParticipantConstraintFunction() { + } + + public static AssignedParticipantConstraintFunction create() { + return new AssignedParticipantConstraintFunction<>(); + } + + /** + * Evalúa si el participante actual está asignado a esta política. + * + * @param operator El operador de comparación (soporta: eq, isAnyOf, isNoneOf) + * @param rightOperand El DID del participante asignado o lista separada por comas + * @param permission El permiso que se está evaluando + * @param context El contexto de la política con información del participante + * @return true si el participante está autorizado según la asignación, false en caso contrario + */ + + @Override + public boolean evaluate(Operator operator, Object rightOperand, Permission permission, C context) { + // Valida que el operador sea soportado + if (!isSupportedOperator(operator)) { + context.reportProblem("Unsupported operator '%s' for AssignedParticipant. Supported: eq, isAnyOf, isNoneOf".formatted(operator)); + return false; + } + + // Obtener participante del contexto + var participantAgent = context.participantAgent(); + if (participantAgent == null) { + context.reportProblem("No ParticipantAgent found in policy context"); + return false; + } + + // Obtener la identidad del participante (su DID) + var participantId = participantAgent.getIdentity(); + if (participantId == null || participantId.isBlank()) { + context.reportProblem("ParticipantAgent does not have an identity (DID)"); + return false; + } + + // Parsear los participantes asignados del rightOperand + var assignedParticipants = parseRightOperand(rightOperand); + if (assignedParticipants.isEmpty()) { + context.reportProblem("No assigned participants found in rightOperand"); + return false; + } + + // Evaluar según el operador + return switch (operator) { + case EQ -> evaluateEquals(participantId, assignedParticipants, context); + case IS_ANY_OF -> evaluateIsAnyOf(participantId, assignedParticipants, context); + case IS_NONE_OF -> evaluateIsNoneOf(participantId, assignedParticipants, context); + default -> { + context.reportProblem("Unsupported operator: %s".formatted(operator)); + yield false; + } + }; + } + + /** + * Evalúa IS_NONE_OF: el participante NO debe estar en la lista de bloqueados. + * Permite a todos los participantes EXCEPTO los que están en la lista. + * El participante actual NO debe coincidir con ninguno de los DIDs en la lista. + */ + private boolean evaluateIsNoneOf(String participantId, List blockedParticipants, C context) { + boolean matches = blockedParticipants.stream() + .noneMatch(blocked -> Objects.equals(participantId, blocked)); + + if (!matches) { + context.reportProblem( + "Participant '%s' is in the blocked participants list: %s" + .formatted(participantId, blockedParticipants) + ); + } + return matches; + } + + /** + * Evalúa IS_ANY_OF: el participante debe estar en la lista de asignados. + * Permite múltiples participantes asignados. El participante actual debe + * coincidir con al menos uno de los DIDs en la lista. + */ + private boolean evaluateIsAnyOf(String participantId, List assignedParticipants, C context) { + boolean matches = assignedParticipants.stream() + .anyMatch(assigned -> Objects.equals(participantId, assigned) + ); + + if (!matches) { + context.reportProblem( + "Participant '%s' is not in the list of assigned participants: %s" + .formatted(participantId, assignedParticipants) + ); + } + return matches; + } + + /** + * Evalúa EQ: el participante debe ser exactamente el asignado. + * Este operador espera un único participante en el rightOperand. + */ + private boolean evaluateEquals(String participantId, List assignedParticipants, C context) { + // Para eq, solo debería haber un participante asignado + if (assignedParticipants.size() > 1) { + context.reportProblem("Operator 'eq' expects a single assigned participant, but got %d. Use 'isAnyOf' for multiple participants."); + return false; + } + + String assignedParticipant = assignedParticipants.get(0); + boolean matches = Objects.equals(participantId, assignedParticipant); + + if (!matches) { + context.reportProblem("Participant '%s' is not the assigned participant. Expected: '%s'".formatted(participantId, assignedParticipant) + ); + } + + return matches; + + } + + /** + * Parsea el rightOperand a una lista de DIDs de participantes asignados. + * Acepta formatos: + * - Un solo DID: "did:web:localhost%3A7083" + * - Múltiples DIDs separados por coma: "did:web:consumer1,did:web:consumer2" + */ + private List parseRightOperand(Object rightOperand) { + if (rightOperand == null) { + return List.of(); + } + + String rightOpStr = rightOperand.toString(); + return Arrays.stream(rightOpStr.split(",")) + .map(String::trim) + .filter(s -> !s.isEmpty()) + .collect(Collectors.toList()); + } + + /** + * Verifica si el operador es soportado por esta función. + */ + private boolean isSupportedOperator(Operator operator) { + return operator == Operator.EQ || + operator == Operator.IS_ANY_OF || + operator == Operator.IS_NONE_OF; + } +} diff --git a/extensions/dcp-impl/src/main/java/org/eclipse/edc/demo/dcp/policy/PolicyEvaluationExtension.java b/extensions/dcp-impl/src/main/java/org/eclipse/edc/demo/dcp/policy/PolicyEvaluationExtension.java index 01b761a17..746076eea 100644 --- a/extensions/dcp-impl/src/main/java/org/eclipse/edc/demo/dcp/policy/PolicyEvaluationExtension.java +++ b/extensions/dcp-impl/src/main/java/org/eclipse/edc/demo/dcp/policy/PolicyEvaluationExtension.java @@ -27,6 +27,7 @@ import org.eclipse.edc.spi.system.ServiceExtension; import org.eclipse.edc.spi.system.ServiceExtensionContext; +import static org.eclipse.edc.demo.dcp.policy.AssignedParticipantConstraintFunction.ASSIGNED_PARTICIPANT_KEY; import static org.eclipse.edc.demo.dcp.policy.MembershipCredentialEvaluationFunction.MEMBERSHIP_CONSTRAINT_KEY; import static org.eclipse.edc.policy.model.OdrlNamespace.ODRL_SCHEMA; @@ -46,6 +47,7 @@ public void initialize(ServiceExtensionContext context) { bindPermissionFunction(MembershipCredentialEvaluationFunction.create(), CatalogPolicyContext.class, CatalogPolicyContext.CATALOG_SCOPE, MEMBERSHIP_CONSTRAINT_KEY); registerDataAccessLevelFunction(); + registerAssignedParticipantFunction(); } @@ -72,4 +74,10 @@ private void bindDutyFunction(AtomicConstraintRuleFunc policyEngine.registerFunction(contextClass, Duty.class, constraintType, function); } + + private void registerAssignedParticipantFunction() { + bindPermissionFunction(AssignedParticipantConstraintFunction.create(), CatalogPolicyContext.class, CatalogPolicyContext.CATALOG_SCOPE, ASSIGNED_PARTICIPANT_KEY); + bindPermissionFunction(AssignedParticipantConstraintFunction.create(), ContractNegotiationPolicyContext.class, ContractNegotiationPolicyContext.NEGOTIATION_SCOPE, ASSIGNED_PARTICIPANT_KEY); + bindPermissionFunction(AssignedParticipantConstraintFunction.create(), TransferProcessPolicyContext.class, TransferProcessPolicyContext.TRANSFER_SCOPE, ASSIGNED_PARTICIPANT_KEY); + } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index da0ec0822..359c1bb91 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -105,6 +105,12 @@ edc-bom-identityhub-sql = { module = "org.eclipse.edc:identityhub-feature-sql-bo edc-bom-issuerservice = { module = "org.eclipse.edc:issuerservice-bom", version.ref = "edc" } edc-bom-issuerservice-sql = { module = "org.eclipse.edc:issuerservice-feature-sql-bom", version.ref = "edc" } +# AWS +edc-aws-s3-core = { module = "org.eclipse.edc.aws:aws-s3-core", version.ref = "edc" } +edc-aws-data-plane-s3 = { module = "org.eclipse.edc.aws:data-plane-aws-s3", version.ref = "edc" } +edc-aws-validator-data-address-s3 = { module = "org.eclipse.edc.aws:validator-data-address-s3", version.ref = "edc" } + + [bundles] connector = [ "edc-boot", diff --git a/launchers/controlplane/build.gradle.kts b/launchers/controlplane/build.gradle.kts index d09d3d2a0..2cf3deef6 100644 --- a/launchers/controlplane/build.gradle.kts +++ b/launchers/controlplane/build.gradle.kts @@ -21,9 +21,10 @@ plugins { dependencies { runtimeOnly(project(":extensions:did-example-resolver")) runtimeOnly(project(":extensions:dcp-impl")) // some patches/impls for DCP - runtimeOnly(project(":extensions:catalog-node-resolver")) // to trigger the federated catalog + runtimeOnly(project(":extensions:catalog-node-resolver")) // Removed: participants managed by kordat project, no federated catalog runtimeOnly(libs.edc.bom.controlplane) runtimeOnly(libs.edc.api.secrets) + runtimeOnly(libs.edc.aws.validator.data.address.s3) if (project.properties.getOrDefault("persistence", "false") == "true") { runtimeOnly(libs.edc.vault.hashicorp) diff --git a/launchers/dataplane/build.gradle.kts b/launchers/dataplane/build.gradle.kts index 71964e2a6..ba152556e 100644 --- a/launchers/dataplane/build.gradle.kts +++ b/launchers/dataplane/build.gradle.kts @@ -19,9 +19,19 @@ plugins { } dependencies { + implementation(libs.edc.aws.s3.core) + implementation(libs.edc.aws.data.plane.s3) + runtimeOnly(libs.edc.bom.dataplane) runtimeOnly(libs.edc.dataplane.v2) + + + // S3 support for data plane + // Note: This may need to be adjusted based on actual EDC version and available extensions + // If data-plane-s3 extension is not available, HTTP can be used as fallback + runtimeOnly(libs.edc.aws.validator.data.address.s3) + if (project.properties.getOrDefault("persistence", "false") == "true") { runtimeOnly(libs.edc.vault.hashicorp) runtimeOnly(libs.edc.bom.dataplane.sql) diff --git a/seed-k8s.sh b/seed-k8s.sh index 56f1e7b2a..3eb0f063f 100755 --- a/seed-k8s.sh +++ b/seed-k8s.sh @@ -21,7 +21,7 @@ echo echo echo "Seed data to 'provider-qna' and 'provider-manufacturing'" -for url in 'http://127.0.0.1/provider-manufacturing/cp' 'http://127.0.0.1/provider-qna/cp' +for url in 'http://127.0.0.1:8088/provider-manufacturing/cp' 'http://127.0.0.1:8088/provider-qna/cp' do newman run \ --folder "Seed" \ @@ -35,7 +35,7 @@ echo echo "Create linked assets on the Catalog Server" newman run \ --folder "Seed Catalog Server" \ - --env-var "HOST=http://127.0.0.1/provider-catalog-server/cp" \ + --env-var "HOST=http://127.0.0.1:8088/provider-catalog-server/cp" \ --env-var "PROVIDER_QNA_DSP_URL=http://provider-qna-controlplane:8082" \ --env-var "PROVIDER_MF_DSP_URL=http://provider-manufacturing-controlplane:8082" \ ./deployment/postman/MVD.postman_collection.json @@ -75,7 +75,7 @@ DATA_CONSUMER=$(jq -n --arg url "$CONSUMER_CONTROLPLANE_SERVICE_URL" --arg ihurl } }') -curl --location "http://127.0.0.1/consumer/cs/api/identity/v1alpha/participants/" \ +curl --location "http://127.0.0.1:8088/consumer/cs/api/identity/v1alpha/participants/" \ --header 'Content-Type: application/json' \ --header "x-api-key: $API_KEY" \ --data "$DATA_CONSUMER" @@ -105,7 +105,7 @@ DATA_PROVIDER=$(jq -n --arg url "$PROVIDER_CONTROLPLANE_SERVICE_URL" --arg ihurl ], "active": true, "participantId": "did:web:provider-identityhub%3A7083:provider", - "did": "did:web:provider-identityhub%3A7083:provider", + "did": "did:web:provider-identityhub%3A7083:provide/seed-k8s.shr", "key":{ "keyId": "did:web:provider-identityhub%3A7083:provider#key-1", "privateKeyAlias": "did:web:provider-identityhub%3A7083:provider#key-1", @@ -115,7 +115,7 @@ DATA_PROVIDER=$(jq -n --arg url "$PROVIDER_CONTROLPLANE_SERVICE_URL" --arg ihurl } }') -curl --location "http://127.0.0.1/provider/cs/api/identity/v1alpha/participants/" \ +curl --location "http://127.0.0.1:8088/provider/cs/api/identity/v1alpha/participants/" \ --header 'Content-Type: application/json' \ --header "x-api-key: $API_KEY" \ --data "$DATA_PROVIDER" @@ -148,14 +148,14 @@ DATA_ISSUER=$(jq -n --arg pem "$PEM_ISSUER" '{ } }') -curl -s --location 'http://127.0.0.1/issuer/cs/api/identity/v1alpha/participants/' \ +curl -s --location 'http://127.0.0.1:8088/issuer/cs/api/identity/v1alpha/participants/' \ --header 'Content-Type: application/json' \ --data "$DATA_ISSUER" ## Seed participant data to the issuer service newman run \ --folder "Seed Issuer SQL" \ - --env-var "ISSUER_ADMIN_URL=http://127.0.0.1/issuer/ad" \ + --env-var "ISSUER_ADMIN_URL=http://127.0.0.1:8088/issuer/ad" \ --env-var "CONSUMER_ID=did:web:consumer-identityhub%3A7083:consumer" \ --env-var "CONSUMER_NAME=MVD Consumer Participant" \ --env-var "PROVIDER_ID=did:web:provider-identityhub%3A7083:provider" \