Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 58 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,75 +1,93 @@
# Construct-X EDC
# Tractus-X EDC (Eclipse Dataspace Connector)

[![Contributors][contributors-shield]][contributors-url]
[![Stargazers][stars-shield]][stars-url]
[![Apache 2.0 License][license-shield]][license-url]

[Construct-X](https://www.construct-x.org/) specific Eclipse Dataspace Connector distributions and extensions, based on the [Eclipse Tractus-X EDC](https://github.com/eclipse-tractusx/tractusx-edc).
[![Latest Release][release-shield]][release-url]
[![Latest Snapshot][snapshot-shield]]()

## Overview
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=eclipse-tractusx_tractusx-edc&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=eclipse-tractusx_tractusx-edc)

The Construct-X EDC extends the Eclipse Tractus-X EDC with
Construct-X specific policies, extensions and configurations.
Container images and deployments of the Eclipse Dataspace Components for the Tractus-X project.

This repository provides:
- Construct-X specific EDC extensions
- Control-Plane and Data-Plane distributions
- Helm charts and docker compose
- Local development and testing environments
Please also refer to:

## Inventory
- [Our docs](https://github.com/eclipse-tractusx/tractusx-edc/tree/main/docs)
- [Our Releases](https://github.com/eclipse-tractusx/tractusx-edc/releases)
- [Eclipse Dataspace Components](https://github.com/eclipse-edc/Connector)
- [Report Bug / Request Feature](https://github.com/eclipse-tractusx/tractusx-edc/issues)

The Construct-X EDC is split into a Control Plane and a Data Plane.
## About The Project

The Control Plane is responsible for resource management,
contract negotiation and transfer orchestration.
The project provides pre-built control- and data-plane [docker](https://www.docker.com/) images
and [helm](https://helm.sh/) charts of
the [Eclipse DataSpaceConnector Project](https://github.com/eclipse-edc/Connector).

The Data Plane handles the actual transfer of data streams.
## Inventory

### Control Plane distributions
The eclipse data space connector is split up into Control-Plane and Data-Plane, whereas the Control-Plane functions as
administration layer and has responsibility of resource management, contract negotiation and administer data transfer.
The Data-Plane does the heavy lifting of transferring and receiving data streams.

- [edc-controlplane-postgresql-hashicorp-vault](edc-controlplane/edc-controlplane-construct-x/con-x-controlplane-postgresql-hashicorp-vault) with
dependencies on
Control-Plane distribution:

- [edc-controlplane-postgresql-hashicorp-vault](edc-controlplane/edc-controlplane-postgresql-hashicorp-vault) with
dependency onto
- [Hashicorp Vault](https://www.vaultproject.io/)
- [PostgreSQL 8.2 or newer](https://www.postgresql.org/)
- [edc-runtime-memory](edc-controlplane/edc-runtime-memory)

### Data Plane distributions
Data-Plane distribution:

- [edc-dataplane-hashicorp-vault](edc-dataplane/edc-dataplane-construct-x/con-x-dataplane-postgresql-hashicorp-vault) with dependencies on
- [edc-dataplane-hashicorp-vault](edc-dataplane/edc-dataplane-hashicorp-vault) with dependency onto
- [Hashicorp Vault](https://www.vaultproject.io/)

## Upstream References
For testing/development purposes:

- [Eclipse Tractus-X EDC](https://github.com/eclipse-tractusx/tractusx-edc)
- [Eclipse Dataspace Components](https://github.com/eclipse-edc/Connector)
- [edc-runtime-memory](edc-controlplane/edc-runtime-memory)

## Construct-X Extensions
## Getting Started

Construct-X adds custom integrations and runtime extensions
on top of the Eclipse Tractus-X EDC.
### Build

This includes:
- Construct-X specific policy extensions
- Custom credential handling
- Wallet integration support
- Local testbed environments
Build Tractus-X EDC together with its Container Images

## Getting Started
```shell
./gradlew dockerize
```

The local testbed provides a lightweight environment for local Construct-X EDC development and integration testing.
It is the recommended starting point for developers getting started with the Construct-X EDC.
## Known Incompatibilities

- Hashicorp Vault 1.18.1 is not compatible with the EDC due to a bug in the vault concerning path handling
- [Internal Issue](https://github.com/eclipse-tractusx/tractusx-edc/issues/1772)
- [Hashicorp Vault Issue](https://github.com/hashicorp/vault/issues/29357)

- [Construct-X Local Testbed](https://github.com/project-construct-x/constructx-edc/blob/develop/edc-controlplane/edc-controlplane-construct-x/local/README.md)

## Contributing
See [CONTRIBUTING](https://github.com/project-construct-x/constructx-edc/blob/develop/CONTRIBUTING.md).
See [CONTRIBUTING](https://github.com/eclipse-tractusx/tractusx-edc/blob/main/CONTRIBUTING.md).

## License

Distributed under the Apache 2.0 License.
See [LICENSE](https://github.com/project-construct-x/constructx-edc/blob/develop/LICENSE) for more information.
See [LICENSE](https://github.com/eclipse-tractusx/tractusx-edc/blob/main/LICENSE) for more information.

<!-- MARKDOWN LINKS & IMAGES -->
<!-- https://www.markdownguide.org/basic-syntax/#reference-style-links -->

[license-shield]: https://img.shields.io/github/license/project-construct-x/constructx-edc.svg?style=for-the-badge
[license-url]: https://github.com/project-construct-x/constructx-edc/blob/develop/LICENSE
[contributors-shield]: https://img.shields.io/github/contributors/eclipse-tractusx/tractusx-edc.svg?style=for-the-badge

[contributors-url]: https://github.com/eclipse-tractusx/tractusx-edc/graphs/contributors

[stars-shield]: https://img.shields.io/github/stars/eclipse-tractusx/tractusx-edc.svg?style=for-the-badge

[stars-url]: https://github.com/eclipse-tractusx/tractusx-edc/stargazers

[license-shield]: https://img.shields.io/github/license/eclipse-tractusx/tractusx-edc.svg?style=for-the-badge

[license-url]: https://github.com/eclipse-tractusx/tractusx-edc/blob/main/LICENSE

[release-shield]: https://img.shields.io/github/v/release/eclipse-tractusx/tractusx-edc.svg?style=for-the-badge

[release-url]: https://github.com/eclipse-tractusx/tractusx-edc/releases

[snapshot-shield]: https://img.shields.io/badge/dynamic/regex?url=https%3A%2F%2Fraw.githubusercontent.com%2Feclipse-tractusx%2Ftractusx-edc%2Frefs%2Fheads%2Fgh-pages%2Fmisc%2Flatest-versioned-snapshot.txt&search=.*&style=for-the-badge&label=Latest-Snapshot
6 changes: 3 additions & 3 deletions charts/tractusx-connector/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ dependencies:
repository: https://helm.releases.hashicorp.com
condition: install.vault
# PostgreSQL
- name: postgresql
- name: postgres
alias: postgresql
version: "15.2.1"
repository: https://charts.bitnami.com/bitnami
version: 0.19.5
repository: oci://registry-1.docker.io/cloudpirates
condition: install.postgresql
140 changes: 140 additions & 0 deletions charts/tractusx-connector/templates/configmap-vault-init.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#################################################################################
# Copyright (c) 2026 Zentralverband der Deutschen Elektro- und Informationstechnischen Handwerke (ZVEH)
#
# 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
#################################################################################

# this configmap contains the initialization script to generate and store aes and rsa keys into the vault.

{{ if .Values.vault.hashicorp.init.enabled }}
{{- $fullName := .Values.fullnameOverride -}}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ $fullName }}-vault-init
namespace: {{ .Release.Namespace | default "default" | quote }}
labels:
{{- include "txdc.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-weight": "-5"
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
data:
init.sh: |
#!/usr/bin/env sh
set -eu

VAULT="${VAULT_ADDR:?VAULT_ADDR is required}"
TOKEN="${VAULT_TOKEN:?VAULT_TOKEN is required}"
FORCE="${FORCE_REGENERATE:-false}"
SECRETS="${VAULT_SECRET_PATH:-/v1/secret}"
HEALTH="${VAULT_HEALTH_PATH:-/v1/sys/health}"

AES_ALIAS="${AES_KEY_ALIAS:-}"
PRIV_ALIAS="${PRIVATE_KEY_ALIAS:-}"
PUB_ALIAS="${PUBLIC_KEY_ALIAS:-}"

log() { echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] $*" >&2; }

# Check provided Aliases for plausibility (AES or RSA pair must be requested)
if [ -z "$AES_ALIAS" ] && [ -z "$PRIV_ALIAS" ] && [ -z "$PUB_ALIAS" ]; then
log "ERROR: no alias provided. Set AES_KEY_ALIAS and/or PRIVATE_KEY_ALIAS+PUBLIC_KEY_ALIAS."
exit 1
fi
if { [ -n "$PRIV_ALIAS" ] && [ -z "$PUB_ALIAS" ]; } || \
{ [ -z "$PRIV_ALIAS" ] && [ -n "$PUB_ALIAS" ]; }; then
log "ERROR: RSA generation requires BOTH PRIVATE_KEY_ALIAS and PUBLIC_KEY_ALIAS."
exit 1
fi

# Install required tools
if ! command -v openssl >/dev/null 2>&1 \
|| ! command -v curl >/dev/null 2>&1 \
|| ! command -v jq >/dev/null 2>&1; then
log "Installing curl, jq, openssl..."
apk add --no-cache curl jq openssl >/dev/null
fi

log "Waiting for Vault at $VAULT$HEALTH..."
i=0
until curl -fsS --connect-timeout 2 --max-time 5 "$VAULT$HEALTH" >/dev/null 2>&1; do
i=$((i+1))
[ "$i" -gt 60 ] && { log "Vault not ready after 60 attempts."; exit 1; }
sleep 3
done
log "Vault ready."

# Check for existing Secret
secret_exists() {
[ "$(curl -sS -o /dev/null -w "%{http_code}" \
-H "X-Vault-Token: $TOKEN" \
"$VAULT$SECRETS/data/$1")" = "200" ]
}

# Store Secret in Vault
put_secret() {
local alias="$1" payload="$2"
local code
code=$(printf '%s' "$payload" | curl -sS -o /dev/null -w "%{http_code}" \
-H "X-Vault-Token: $TOKEN" \
-H "Content-Type: application/json" \
-X POST --data-binary @- \
"$VAULT$SECRETS/data/$alias")
if [ "$code" != "200" ] && [ "$code" != "204" ]; then
log "Failed to store '$alias' (HTTP $code)"
exit 1
fi
}

# Generate AES Key
if [ -n "$AES_ALIAS" ]; then
if [ "$FORCE" != "true" ] && secret_exists "$AES_ALIAS"; then
log "AES key '$AES_ALIAS' already present — skipping."
else
log "Generating AES-256 key for '$AES_ALIAS'..."
key=$(openssl rand -base64 32 | tr -d '\n')
payload=$(jq -n --arg content "$key" '{data:{content:$content}}')
put_secret "$AES_ALIAS" "$payload"
log "AES key stored at $VAULT$SECRETS/data/$AES_ALIAS"
fi
fi

# Generate RSA Keypair
if [ -n "$PRIV_ALIAS" ] && [ -n "$PUB_ALIAS" ]; then
if [ "$FORCE" != "true" ] \
&& secret_exists "$PRIV_ALIAS" \
&& secret_exists "$PUB_ALIAS"; then
log "RSA keypair ('$PRIV_ALIAS' / '$PUB_ALIAS') already present — skipping."
else
log "Generating RSA keypair ('$PRIV_ALIAS' / '$PUB_ALIAS')..."
umask 077
dir=$(mktemp -d)
openssl genrsa -out "$dir/k.pem" 2048 2>/dev/null
openssl pkcs8 -topk8 -nocrypt -in "$dir/k.pem" -out "$dir/priv.pem"
openssl rsa -in "$dir/k.pem" -pubout -out "$dir/pub.pem" 2>/dev/null

put_secret "$PRIV_ALIAS" \
"$(jq -n --rawfile content "$dir/priv.pem" '{data:{content:$content}}')"
put_secret "$PUB_ALIAS" \
"$(jq -n --rawfile content "$dir/pub.pem" '{data:{content:$content}}')"

rm -rf "$dir"
log "RSA keypair stored at $VAULT$SECRETS/data/{$PRIV_ALIAS,$PUB_ALIAS}"
fi
fi

log "Vault initialization complete."
{{- end }}
87 changes: 87 additions & 0 deletions charts/tractusx-connector/templates/job-vault-init.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#################################################################################
# Copyright (c) 2026 Zentralverband der Deutschen Elektro- und Informationstechnischen Handwerke (ZVEH)
#
# 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
#################################################################################

{{ if .Values.vault.hashicorp.init.enabled -}}
{{- $fullName := .Values.fullnameOverride -}}
apiVersion: batch/v1
kind: Job
metadata:
name: {{ $fullName }}-vault-init
namespace: {{ .Release.Namespace | default "default" | quote }}
labels:
{{- include "txdc.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-weight": "0"
"helm.sh/hook-delete-policy": before-hook-creation
spec:
backoffLimit: 3
ttlSecondsAfterFinished: 600
activeDeadlineSeconds: 300
template:
metadata:
labels:
{{- include "txdc.labels" . | nindent 8 }}
spec:
restartPolicy: OnFailure
serviceAccountName: {{ include "txdc.serviceAccountName" . }}
containers:
- name: vault-init
{{- $img := index .Values "vault" "hashicorp" "init" "image" | default dict }}
image: {{ $img.repository | default "alpine" }}:{{ $img.tag | default "3.20" }}
command: ["/bin/sh", "-c"]
args:
- |
tr -d '\r' < /scripts/init.sh > /tmp/init.sh
exec sh /tmp/init.sh
env:
- name: VAULT_ADDR
value: {{ tpl .Values.vault.hashicorp.url . | quote }}
- name: VAULT_TOKEN
value: {{ .Values.vault.hashicorp.token | required "vault.hashicorp.token is required" }}
- name: VAULT_SECRET_PATH
value: {{ .Values.vault.hashicorp.paths.secret | quote }}
- name: VAULT_HEALTH_PATH
value: {{ .Values.vault.hashicorp.paths.health | quote }}
{{- with .Values.vault.hashicorp.init.forceRegenerate }}
- name: FORCE_REGENERATE
value: {{ . | quote }}
{{- end }}
{{- with .Values.vault.hashicorp.init.aesKeyAlias }}
- name: AES_KEY_ALIAS
value: {{ . | quote }}
{{- end }}
{{- with .Values.dataplane.token.signer.privatekey_alias }}
- name: PRIVATE_KEY_ALIAS
value: {{ . | quote }}
{{- end }}
{{- with .Values.dataplane.token.verifier.publickey_alias }}
- name: PUBLIC_KEY_ALIAS
value: {{ . | quote }}
{{- end }}
volumeMounts:
- name: script
mountPath: /scripts
readOnly: true
volumes:
- name: script
configMap:
name: {{ $fullName }}-vault-init
defaultMode: 0555
{{- end }}
Loading
Loading