From 8d85b847cf81232dd5b04ab8e1f1f71b7ba4ebd7 Mon Sep 17 00:00:00 2001 From: Simon Bergerfurth Date: Wed, 3 Jun 2026 11:43:42 +0200 Subject: [PATCH 1/3] feat: add wallet helm chart --- charts/wallet/.helmignore | 23 + charts/wallet/Chart.lock | 9 + charts/wallet/Chart.yaml | 67 +++ charts/wallet/LICENSE | 201 +++++++++ charts/wallet/README.md | 174 ++++++++ charts/wallet/templates/NOTES.txt | 88 ++++ charts/wallet/templates/_helpers.tpl | 86 ++++ .../templates/configmap-datasource.yaml | 41 ++ .../wallet/templates/configmap-runtime.yaml | 73 ++++ .../templates/configmap-vault-init.yaml | 140 ++++++ charts/wallet/templates/deployment.yaml | 206 +++++++++ charts/wallet/templates/hpa.yaml | 50 +++ charts/wallet/templates/ingress.yaml | 98 +++++ charts/wallet/templates/job-vault-init.yaml | 87 ++++ .../wallet/templates/secret-datasource.yaml | 42 ++ charts/wallet/templates/secret-runtime.yaml | 38 ++ charts/wallet/templates/service.yaml | 52 +++ charts/wallet/templates/serviceaccount.yaml | 33 ++ charts/wallet/templates/tests/test.yaml | 43 ++ charts/wallet/values.yaml | 404 ++++++++++++++++++ 20 files changed, 1955 insertions(+) create mode 100644 charts/wallet/.helmignore create mode 100644 charts/wallet/Chart.lock create mode 100644 charts/wallet/Chart.yaml create mode 100644 charts/wallet/LICENSE create mode 100644 charts/wallet/README.md create mode 100644 charts/wallet/templates/NOTES.txt create mode 100644 charts/wallet/templates/_helpers.tpl create mode 100644 charts/wallet/templates/configmap-datasource.yaml create mode 100644 charts/wallet/templates/configmap-runtime.yaml create mode 100644 charts/wallet/templates/configmap-vault-init.yaml create mode 100644 charts/wallet/templates/deployment.yaml create mode 100644 charts/wallet/templates/hpa.yaml create mode 100644 charts/wallet/templates/ingress.yaml create mode 100644 charts/wallet/templates/job-vault-init.yaml create mode 100644 charts/wallet/templates/secret-datasource.yaml create mode 100644 charts/wallet/templates/secret-runtime.yaml create mode 100644 charts/wallet/templates/service.yaml create mode 100644 charts/wallet/templates/serviceaccount.yaml create mode 100644 charts/wallet/templates/tests/test.yaml create mode 100644 charts/wallet/values.yaml diff --git a/charts/wallet/.helmignore b/charts/wallet/.helmignore new file mode 100644 index 000000000..691fa13d6 --- /dev/null +++ b/charts/wallet/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ \ No newline at end of file diff --git a/charts/wallet/Chart.lock b/charts/wallet/Chart.lock new file mode 100644 index 000000000..f1f29f48f --- /dev/null +++ b/charts/wallet/Chart.lock @@ -0,0 +1,9 @@ +dependencies: +- name: postgresql + repository: https://charts.bitnami.com/bitnami + version: 15.5.38 +- name: vault + repository: https://helm.releases.hashicorp.com + version: 0.29.1 +digest: sha256:5fc0036fab9964c415299544d795eb8b0278c4870f2dd69948a1987870086b05 +generated: "2026-06-01T09:31:30.809792705+02:00" diff --git a/charts/wallet/Chart.yaml b/charts/wallet/Chart.yaml new file mode 100644 index 000000000..11f85ff57 --- /dev/null +++ b/charts/wallet/Chart.yaml @@ -0,0 +1,67 @@ +################################################################################# +# Copyright (c) 2026 Construct-X +# Copyright (c) 2025 Cofinity-X +# Copyright (c) 2025 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 +################################################################################# + +apiVersion: v2 +name: wallet +description: A Helm chart for Construct-X Wallet alongside Hashicorp Vault and PostgreSQL + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "0.17.0-1" +keywords: + - wallet + - identityhub + - edc + - gaia-x +home: https://github.com/project-construct-x/wallet +sources: + - https://github.com/project-construct-x/wallet + - https://github.com/eclipse-tractusx/tractusx-identityhub +dependencies: + # PostgreSQL + - name: postgresql + alias: postgresql + version: 15.5.x + repository: https://charts.bitnami.com/bitnami + condition: install.postgresql + # HashiCorp Vault + - name: vault + alias: vault + version: 0.29.1 + repository: https://helm.releases.hashicorp.com + condition: install.vault diff --git a/charts/wallet/LICENSE b/charts/wallet/LICENSE new file mode 100644 index 000000000..261eeb9e9 --- /dev/null +++ b/charts/wallet/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://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. diff --git a/charts/wallet/README.md b/charts/wallet/README.md new file mode 100644 index 000000000..14497e311 --- /dev/null +++ b/charts/wallet/README.md @@ -0,0 +1,174 @@ +# Construct-X Wallet + +![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) +![License: Apache-2.0](https://img.shields.io/badge/License-Apache--2.0-informational?style=flat-square) + +Deploys the [Construct-X Wallet](https://github.com/project-construct-x/wallet) — an EDC IdentityHub runtime — together with a PostgreSQL database and a HashiCorp Vault instance. + + +## Prerequisites + +| **Requirement** | **Version** | +|---|---| +| Kubernetes | 1.29+ | +| Helm | 3.14+ | + +- A Persistent Volume provisioner is required if `postgresql.primary.persistence.enabled: true` +- Cluster Internet connection is required if `vault.hashicorp.init.enabled: true` to pull required `apk` packages + +## Installation + +```bash +# Add dependencies +helm dependency build +# Install +helm install wallet . -f my-override-values.yaml +``` + +## Values + +### Top-level + +| Key | Type | Default | Description | +|---|---|---|---| +| `install.postgresql` | bool | `true` | Install the bundled PostgreSQL sub-chart. Set to `false` to use an external database. | +| `install.vault` | bool | `true` | Install the bundled Vault sub-chart. Set to `false` to use an external Vault. | +| `fullnameOverride` | string | `"wallet"` | Overrides the chart fullname used for all resource names. | +| `nameOverride` | string | `"wallet"` | Overrides the chart name used in labels. | +| `imagePullSecrets` | list | `[]` | Pull secrets for private image registries. | +| `customCaCerts` | object | `{}` | Custom CA certificates added to the Java truststore at startup. | + +### `wallet` + +| Key | Type | Default | Description | +|---|---|---|---| +| `wallet.image.repository` | string | `ghcr.io/project-construct-x/wallet` | Container image repository. | +| `wallet.image.tag` | string | `0.17.0-1` | Image tag. Defaults to `chart.appVersion` if left empty. | +| `wallet.image.pullPolicy` | string | `IfNotPresent` | Kubernetes image pull policy. | +| `wallet.initContainers` | list | `[]` | Additional init containers run before the wallet starts. | +| `wallet.podLabels` | object | `{}` | Extra labels applied to the wallet pod. | +| `wallet.podAnnotations` | object | `{}` | Extra annotations applied to the wallet pod. | +| `wallet.useSVE` | bool | `false` | Disables SVE CPU instructions via `JAVA_TOOL_OPTIONS`. Enable on SVE-capable nodes if the JVM crashes with illegal instruction errors. | +| `wallet.debug.enabled` | bool | `false` | Enables the JDWP remote debug socket. Never use in production. | +| `wallet.debug.port` | int | `1045` | JDWP listen port inside the container. | +| `wallet.debug.suspendOnStart` | bool | `false` | If `true`, the JVM suspends until a debugger connects. | +| `wallet.hostname` | string | `wallet.staging.construct-x.net` | Public hostname. Used in `did:web` URLs and ingress routing. | +| `wallet.superuser.createSecret` | bool | `true` | Creates a Kubernetes Secret from the values below and mounts it via `envFrom`. Set to `false` and reference an external secret via `envSecretNames` instead. | +| `wallet.superuser.id` | string | `admin` | Participant context ID of the super-user. | +| `wallet.superuser.apiKey` | string | `YWRtaW4.adminKey` | API key for the super-user. Format: `base64().`. **Change before production use.** | +| `wallet.superuser.publicKeyAlias` | string | `admin#pubkey` | Vault alias for the super-user RSA public key. Generated by the wallet on first start. | +| `wallet.superuser.privateKeyAlias` | string | `admin#privkey` | Vault alias for the super-user RSA private key. Generated by the wallet on first start. | +| `wallet.didweb.https` | bool | `true` | Use `https://` in `did:web` URLs. Set to `false` only for local testing. | +| `wallet.env` | object | `{}` | Extra plain environment variables injected into the wallet pod. | +| `wallet.envValueFrom` | object | `{}` | Extra environment variables sourced from ConfigMaps or Secrets via `valueFrom`. | +| `wallet.envSecretNames` | list | `[]` | Names of existing Secrets whose keys are mounted as environment variables via `envFrom`. | +| `wallet.envConfigMapNames` | list | `[]` | Names of existing ConfigMaps whose keys are mounted as environment variables via `envFrom`. | +| `wallet.replicaCount` | int | `1` | Number of wallet pod replicas. | +| `wallet.resources.limits.cpu` | string | `500m` | CPU limit for the wallet container. | +| `wallet.resources.limits.memory` | string | `512Mi` | Memory limit for the wallet container. | +| `wallet.resources.requests.cpu` | string | `250m` | CPU request for the wallet container. | +| `wallet.resources.requests.memory` | string | `128Mi` | Memory request for the wallet container. | +| `wallet.autoscaling.enabled` | bool | `false` | Enables Horizontal Pod Autoscaling. | +| `wallet.autoscaling.minReplicas` | int | `1` | Minimum number of replicas under HPA. | +| `wallet.autoscaling.maxReplicas` | int | `100` | Maximum number of replicas under HPA. | +| `wallet.autoscaling.targetCPUUtilizationPercentage` | int | `80` | CPU utilisation target for HPA scale-out. | +| `wallet.autoscaling.targetMemoryUtilizationPercentage` | int | `80` | Memory utilisation target for HPA scale-out. | +| `wallet.nodeSelector` | object | `{}` | Node selector constraints for the wallet pod. | +| `wallet.tolerations` | list | `[]` | Tolerations for the wallet pod. | +| `wallet.affinity` | object | `{}` | Affinity rules for the wallet pod. | +| `wallet.volumeMounts` | list | `[]` | Additional volume mounts for the wallet container. | +| `wallet.volumes` | list | `[]` | Additional volumes for the wallet pod. | + +### `wallet.endpoints` + +Each endpoint creates a Kubernetes Service port and injects the corresponding `WEB_HTTP_*` environment variables into the wallet. Only endpoints listed under an ingress' `endpoints` array are exposed externally. + +| Key | Default port | Default path | Description | +|---|---|---|---| +| `wallet.endpoints.default` | `8181` | `/api` | Observability endpoint (health checks). Must not be added to public ingresses. | +| `wallet.endpoints.identity` | `15151` | `/api/identity` | Management API. Protected by `X-Api-Key`. Must not be internet-facing. | +| `wallet.endpoints.identity.authKeyAlias` | `sup3r$3cr3t` | — | Vault alias whose stored value is validated against the `X-Api-Key` request header. | +| `wallet.endpoints.credentials` | `13131` | `/api/credentials` | DCP Credential Offer and Presentation API. Public-facing in DCP flows. | +| `wallet.endpoints.did` | `80` | `/` | DID document service. Resolves `did:web` documents. Must be publicly reachable. | +| `wallet.endpoints.sts` | `9292` | `/api/sts` | Secure Token Service. Issues self-signed ID tokens for DCP flows. Public-facing. | + +### `wallet.livenessProbe` / `wallet.readinessProbe` + +Both probes call `GET /check/liveness` and `GET /check/readiness` on the `default` endpoint port. + +| Key | Type | Default | Description | +|---|---|---|---| +| `*.enabled` | bool | `true` | Whether the probe is active. | +| `*.initialDelaySeconds` | int | `5` | Seconds before the first probe fires. Increase to 30+ on slow cold starts. | +| `*.periodSeconds` | int | `5` | Interval between probes. | +| `*.timeoutSeconds` | int | `5` | Seconds before a probe attempt times out. | +| `*.failureThreshold` | int | `6` | Consecutive failures before the pod is restarted or marked not-ready. | +| `*.successThreshold` | int | `1` | Consecutive successes to transition back to healthy. | + +### `wallet.service` + +| Key | Type | Default | Description | +|---|---|---|---| +| `wallet.service.type` | string | `ClusterIP` | Kubernetes Service type. `ClusterIP` is recommended when an ingress or Istio gateway is used. | +| `wallet.service.annotations` | object | `{}` | Annotations added to the Service resource. | + +### `wallet.ingresses` + +A list of Ingress definitions. Each entry creates one Ingress resource routing the listed endpoints. The chart ships two pre-configured entries (public and internal). Only entries with `enabled: true` are rendered. + +| Key | Type | Description | +|---|---|---| +| `*.enabled` | bool | Render this Ingress resource. | +| `*.hostname` | string | Hostname for all routes in this Ingress. | +| `*.annotations` | object | Annotations added to the Ingress (e.g. cert-manager, external-dns). | +| `*.endpoints` | list | Names of `wallet.endpoints` keys to expose via this Ingress. | +| `*.className` | string | Ingress class name (e.g. `nginx`, `traefik`). | +| `*.tls.enabled` | bool | Attach a TLS block to this Ingress. | +| `*.tls.secretName` | string | Name of the Secret holding the TLS certificate. | +| `*.certManager.issuer` | string | cert-manager namespace-scoped issuer. | +| `*.certManager.clusterIssuer` | string | cert-manager cluster-scoped issuer. | + +### `serviceAccount` + +| Key | Type | Default | Description | +|---|---|---|---| +| `serviceAccount.create` | bool | `true` | Create a dedicated ServiceAccount for the wallet and vault-init job. | +| `serviceAccount.automount` | bool | `true` | Automatically mount the ServiceAccount token into pods. | +| `serviceAccount.annotations` | object | `{}` | Annotations added to the ServiceAccount (e.g. for Vault Kubernetes auth). | +| `serviceAccount.name` | string | `""` | Override the generated ServiceAccount name. | + +### `postgresql` + +The chart uses the Bitnami legacy PostgreSQL sub-chart. + +| Key | Type | Default | Description | +|---|---|---|---| +| `postgresql.jdbcUrl` | string | `jdbc:postgresql://wallet-postgresql:5432/wallet` | JDBC URL passed to the wallet. | +| `postgresql.auth.database` | string | `wallet` | Database name created on first start. | +| `postgresql.auth.username` | string | `user` | Database user the wallet connects as. | +| `postgresql.auth.password` | string | `password` | Database password. **Change before production use.** | +| `postgresql.primary.persistence.enabled` | bool | `true` | Persist primary node data. Disable only for throwaway test environments. | +| `postgresql.readReplicas.persistence.enabled` | bool | `false` | Persist read-replica data. | + +### `vault` + +| Key | Type | Default | Description | +|---|---|---|---| +| `vault.injector.enabled` | bool | `false` | Vault Agent Injector sidecar. Disabled — the wallet reads secrets directly via the Vault HTTP API. | +| `vault.server.dev.enabled` | bool | `true` | Run Vault in dev mode (in-memory, no persistence). **Disable for production.** | +| `vault.server.dev.devRootToken` | string | `root` | Root token for dev mode. Must match `vault.hashicorp.token`. | +| `vault.server.postStart` | string | `nil` | Optional post-start script executed inside the Vault container. Must be set externally. | +| `vault.hashicorp.url` | string | `http://wallet-vault:8200` | Vault address reachable from within the cluster. | +| `vault.hashicorp.token` | string | `root` | Vault token used by the wallet at runtime. **Change before production use.** | +| `vault.hashicorp.timeout` | int | `30` | Vault HTTP client timeout in seconds. | +| `vault.hashicorp.healthCheck.enabled` | bool | `true` | Whether the wallet checks Vault health on startup. | +| `vault.hashicorp.healthCheck.standbyOk` | bool | `true` | Treat Vault HA standby nodes as healthy. | +| `vault.hashicorp.paths.secret` | string | `/v1/secret` | Mount path for all wallet secrets. | +| `vault.hashicorp.paths.health` | string | `/v1/sys/health` | Vault health endpoint polled by the wallet and vault-init job. | +| `vault.hashicorp.init.enabled` | bool | `true` | Run the post-install vault-init job that seeds required Vault secrets. | +| `vault.hashicorp.init.aesKeyAlias` | string | `wallet-aes-key-alias` | Vault alias for the AES-256 encryption key. | + +## Sources + +- Code: [Construct-X Wallet](https://github.com/project-construct-x/wallet) +- Chart: [Tractus-X IdentityHub](https://github.com/eclipse-tractusx/tractusx-identityhub) \ No newline at end of file diff --git a/charts/wallet/templates/NOTES.txt b/charts/wallet/templates/NOTES.txt new file mode 100644 index 000000000..0c643f679 --- /dev/null +++ b/charts/wallet/templates/NOTES.txt @@ -0,0 +1,88 @@ +{{- $fullName := include "wallet.fullname" . -}} +{{- $namespace := .Release.Namespace -}} +================================================================================ + Construct-X Wallet "{{ .Release.Name }}" — installation complete +================================================================================ + + Chart version : {{ .Chart.Version }} + App version : {{ .Chart.AppVersion }} + Namespace : {{ $namespace }} + Release : {{ .Release.Name }} + +================================================================================ + Public endpoints +================================================================================ +{{- $ingressShown := false }} +{{- range .Values.wallet.ingresses }} + {{- if .enabled }} + {{- $ingressShown = true }} + {{- $proto := "http" }} + {{- if .tls.enabled }}{{ $proto = "https" }}{{ end }} + + Ingress on {{ .hostname }} (className: {{ .className | default "default" }}) + {{- range .endpoints }} + {{- $ep := index $.Values.wallet.endpoints . }} + {{- if $ep }} + {{ printf "%-15s" . }} {{ $proto }}://{{ index $.Values.wallet.ingresses 0 "hostname" }}{{ $ep.path }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} +{{- if not $ingressShown }} + No ingress is enabled. Endpoints are reachable inside the cluster only: + + kubectl port-forward -n {{ $namespace }} svc/{{ $fullName }} \ + {{- range $name, $ep := .Values.wallet.endpoints }} + {{ $ep.port }}:{{ $ep.port }} {{- end }} + + Then locally: + {{- range $name, $ep := .Values.wallet.endpoints }} + {{ printf "%-15s" $name }} http://localhost:{{ $ep.port }}{{ $ep.path }} + {{- end }} +{{- end }} + +{{- if eq .Values.wallet.superuser.createSecret true }} +================================================================================ + Super-User participant +================================================================================ + + The wallet auto-seeds a super-user on first start: + Participant ID : {{ .Values.wallet.superuser.id }} + API key : {{ .Values.wallet.superuser.apiKey }} + Public key alias: {{ .Values.wallet.superuser.publicKeyAlias }} + Private key alias: {{ .Values.wallet.superuser.privateKeyAlias }} + + If you reinstall while keeping PostgreSQL persistence, the participant context + remains and the seed is skipped. Wipe with: + kubectl exec -n {{ $namespace }} -it \ + $(kubectl get pod -n {{ $namespace }} -l app.kubernetes.io/name=postgresql -o name | head -1) -- \ + psql -U {{ .Values.postgresql.auth.username }} -d {{ .Values.postgresql.auth.database }} \ + -c "DELETE FROM participant_context WHERE participant_context_id = '{{ .Values.wallet.superuser.id }}';" + kubectl rollout restart -n {{ $namespace }} deploy/{{ $fullName }} + + {{- if eq (default "YWRtaW4.adminKey" .Values.wallet.superuser.apiKey) "YWRtaW4.adminKey" }} + + ⚠ WARNING: Super-User Extension is using the default API key. Change wallet.superuser.apiKey + before production use. + {{- end }} +{{- end }} +================================================================================ +{{- if not .Values.wallet.didweb.https }} + + ⚠ WARNING: didweb.https is set to false. did:web URLs will use HTTP. + This is only acceptable for local testing — switch to true before going public. +{{- end }} +{{- if eq .Values.vault.server.dev.enabled true }} + + ⚠ WARNING: Vault is running in dev mode. All secrets are lost on pod restart. + For production, set vault.server.dev.enabled=false and configure persistence. +{{- end }} +{{- if eq (default "root" .Values.vault.hashicorp.token) "root" }} + + ⚠ WARNING: vault.hashicorp.token is set to "root" (dev-mode default). Change vault.hashicorp.token before production use. +{{- end }} +{{- if eq (default "password" .Values.postgresql.auth.password) "password" }} + + ⚠ WARNING: PostgreSQL is using the default password. Change postgresql.auth.password + before production use. +{{- end }} diff --git a/charts/wallet/templates/_helpers.tpl b/charts/wallet/templates/_helpers.tpl new file mode 100644 index 000000000..9ef69aa42 --- /dev/null +++ b/charts/wallet/templates/_helpers.tpl @@ -0,0 +1,86 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "wallet.name" -}} +{{- default .Chart.Name .Values.nameOverride | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "wallet.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "wallet.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Control Common labels +*/}} +{{- define "wallet.labels" -}} +helm.sh/chart: {{ include "wallet.chart" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Control Common Server labels +*/}} +{{- define "wallet.server.labels" -}} +helm.sh/chart: {{ include "wallet.chart" . }} +{{ include "wallet.server.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/component: wallet-server +app.kubernetes.io/part-of: wallet +{{- end }} + +{{/* +Control Selector labels +*/}} +{{- define "wallet.server.selectorLabels" -}} +app.kubernetes.io/name: {{ include "wallet.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "wallet.server.serviceaccount.name" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "wallet.fullname" . ) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "wallet.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "wallet.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/wallet/templates/configmap-datasource.yaml b/charts/wallet/templates/configmap-datasource.yaml new file mode 100644 index 000000000..fd291c723 --- /dev/null +++ b/charts/wallet/templates/configmap-datasource.yaml @@ -0,0 +1,41 @@ +################################################################################# +# Copyright (c) 2026 Construct-X +# Copyright (c) 2025 Cofinity-X +# Copyright (c) 2025 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 +################################################################################# + +# this configmap contains all database configuration that is required by the wallet runtime. + +{{ $fullName := .Values.fullnameOverride -}} +{{- $postgresql := index .Values "postgresql" | default dict }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ $fullName }}-datasource-config + namespace: {{ .Release.Namespace | default "default" | quote }} + labels: + {{- include "wallet.labels" . | nindent 4 }} +data: + + ################ + ## POSTGRESQL ## + ################ + + # default + EDC_SQL_SCHEMA_AUTOCREATE: {{ $postgresql.schemaAutocreate | default true | quote }} + EDC_DATASOURCE_DEFAULT_URL: {{ tpl .Values.postgresql.jdbcUrl . | quote }} diff --git a/charts/wallet/templates/configmap-runtime.yaml b/charts/wallet/templates/configmap-runtime.yaml new file mode 100644 index 000000000..1fa738b71 --- /dev/null +++ b/charts/wallet/templates/configmap-runtime.yaml @@ -0,0 +1,73 @@ +################################################################################# +# Copyright (c) 2026 Construct-X +# Copyright (c) 2025 Cofinity-X +# Copyright (c) 2025 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 +################################################################################# + +# this configmap contains all application configuration that is required by the wallet runtime. + +{{ $fullName := .Values.fullnameOverride -}} +{{- $iam := index .Values "wallet" "iam" | default dict }} +{{- $issuer := index .Values "wallet" "issuer" | default dict }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ $fullName }}-config + namespace: {{ .Release.Namespace | default "default" | quote }} + labels: + {{- include "wallet.labels" . | nindent 4 }} +data: + ####### + # API # + ####### + EDC_HOSTNAME: {{ .Values.wallet.hostname | quote }} + WEB_HTTP_PORT: {{ .Values.wallet.endpoints.default.port | quote }} + WEB_HTTP_PATH: {{ .Values.wallet.endpoints.default.path | quote }} + WEB_HTTP_IDENTITY_PORT: {{ .Values.wallet.endpoints.identity.port | quote }} + WEB_HTTP_IDENTITY_PATH: {{ .Values.wallet.endpoints.identity.path | quote }} + WEB_HTTP_IDENTITY_AUTH_ALIAS: {{ .Values.wallet.endpoints.identity.authKeyAlias | required ".Values.wallet.endpoints.identity.authKeyAlias is required" | quote }} + WEB_HTTP_CREDENTIALS_PORT: {{ .Values.wallet.endpoints.credentials.port | quote }} + WEB_HTTP_CREDENTIALS_PATH: {{ .Values.wallet.endpoints.credentials.path | quote }} + WEB_HTTP_DID_PORT: {{ .Values.wallet.endpoints.did.port | quote }} + WEB_HTTP_DID_PATH: {{ .Values.wallet.endpoints.did.path | quote }} + WEB_HTTP_STS_PORT: {{ .Values.wallet.endpoints.sts.port | quote}} + WEB_HTTP_STS_PATH: {{ .Values.wallet.endpoints.sts.path | quote}} + + #################### + ## IAM/DID/Issuer ## + #################### + EDC_IAM_DID_WEB_USE_HTTPS: {{ .Values.wallet.didweb.https | quote }} + EDC_IAM_KEY_ALGORITHM: {{ $iam.keyAlgorithm | default "RSA" | quote }} + EDC_IAM_CREDENTIAL_RENEWAL_GRACEPERIOD: {{ $iam.renewalGraceperiod | default "172800" | quote }} + EDC_ISSUER_ISSUANCE_SEND_RETRY_LIMIT: {{ $issuer.sendRetryLimit | default "0" | quote }} + + ########### + ## VAULT ## + ########### + EDC_VAULT_HASHICORP_URL: {{ tpl .Values.vault.hashicorp.url . | quote }} + EDC_VAULT_HASHICORP_TIMEOUT_SECONDS: {{ .Values.vault.hashicorp.timeout | quote }} + EDC_VAULT_HASHICORP_HEALTH_CHECK_ENABLED: {{ .Values.vault.hashicorp.healthCheck.enabled | quote }} + EDC_VAULT_HASHICORP_HEALTH_CHECK_STANDBY_OK: {{ .Values.vault.hashicorp.healthCheck.standbyOk | quote }} + EDC_VAULT_HASHICORP_API_SECRET_PATH: {{ .Values.vault.hashicorp.paths.secret | quote }} + EDC_VAULT_HASHICORP_API_HEALTH_CHECK_PATH: {{ .Values.vault.hashicorp.paths.health | quote }} + + ################# + ## Encryption ## + ################# + EDC_ENCRYPTION_AES_KEY_ALIAS: {{ .Values.vault.hashicorp.init.aesKeyAlias | default "wallet-aes-key-alias" | quote }} + EDC_ISSUER_STATUSLIST_SIGNING_KEY_ALIAS: {{ $issuer.statuslistSigningKeyAlias | default "foo" | quote }} \ No newline at end of file diff --git a/charts/wallet/templates/configmap-vault-init.yaml b/charts/wallet/templates/configmap-vault-init.yaml new file mode 100644 index 000000000..f9308ce3e --- /dev/null +++ b/charts/wallet/templates/configmap-vault-init.yaml @@ -0,0 +1,140 @@ +################################################################################# +# Copyright (c) 2026 Construct-X +# +# 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 "wallet.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 }} diff --git a/charts/wallet/templates/deployment.yaml b/charts/wallet/templates/deployment.yaml new file mode 100644 index 000000000..ef44e7c80 --- /dev/null +++ b/charts/wallet/templates/deployment.yaml @@ -0,0 +1,206 @@ +# +# Copyright (c) 2026 Construct-X +# Copyright (c) 2025 Cofinity-X +# Copyright (c) 2025 LKS Next +# Copyright (c) 2025 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 +# + +{{ $fullName := .Values.fullnameOverride -}} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "wallet.fullname" . }} + labels: + {{- include "wallet.server.labels" . | nindent 4 }} +spec: + {{- if not .Values.wallet.autoscaling.enabled }} + replicas: {{ .Values.wallet.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "wallet.server.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.wallet.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "wallet.server.selectorLabels" . | nindent 8 }} + {{- with .Values.wallet.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "wallet.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.wallet.podSecurityContext | nindent 8 }} + {{- if or .Values.wallet.initContainers .Values.customCaCerts }} + initContainers: + {{- if .Values.wallet.initContainers }} + {{- toYaml .Values.wallet.initContainers | nindent 8 }} + {{- end }} + {{- if .Values.customCaCerts }} + - name: custom-cacerts + # either use the specified image, or use the default one + {{- if .Values.wallet.image.repository }} + image: "{{ .Values.wallet.image.repository }}:{{ .Values.wallet.image.tag | default .Chart.AppVersion }}" + {{- else }} + image: "ghcr.io/project-construct-x/wallet:{{ .Values.wallet.image.tag | default .Chart.AppVersion }}" + {{- end }} + imagePullPolicy: {{ .Values.wallet.image.pullPolicy }} + command: + - /bin/sh + - -c + - | + cp /opt/java/openjdk/lib/security/cacerts /workdir/ + find /cacerts -type f \( -iname \*.crt -o -iname \*.pem \) -exec echo "{}" \; | while read PEM_FILE_PATH; do + PEM_FILE=${PEM_FILE_PATH##*/} + ALIAS=${PEM_FILE%.*} + echo "adding ${PEM_FILE} with alias ${ALIAS} to cacerts ..." + keytool -import -noprompt -trustcacerts -alias ${ALIAS} -file ${PEM_FILE_PATH} -keystore /workdir/cacerts -storepass changeit + done + securityContext: + {{- toYaml .Values.wallet.securityContext | nindent 12 }} + volumeMounts: + - name: custom-cacertificates + mountPath: /cacerts + - name: custom-cacerts + mountPath: /workdir + {{- end }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.wallet.securityContext | nindent 12 }} + # either use the specified image, or use the default one + {{- if .Values.wallet.image.repository }} + image: "{{ .Values.wallet.image.repository }}:{{ .Values.wallet.image.tag | default .Chart.AppVersion }}" + {{- else }} + image: "ghcr.io/project-construct-x/wallet:{{ .Values.wallet.image.tag | default .Chart.AppVersion }}" + {{- end }} + + imagePullPolicy: {{ .Values.wallet.image.pullPolicy }} + ports: + {{- range $key,$value := .Values.wallet.endpoints }} + - name: {{ $key }} + containerPort: {{ $value.port }} + protocol: TCP + {{- end }} + {{- if .Values.wallet.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: {{ .Values.wallet.endpoints.default.path }}/check/liveness + port: {{ .Values.wallet.endpoints.default.port }} + initialDelaySeconds: {{ .Values.wallet.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.wallet.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.wallet.livenessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.wallet.livenessProbe.failureThreshold }} + successThreshold: {{ .Values.wallet.livenessProbe.successThreshold }} + {{- end }} + {{- if .Values.wallet.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: {{ .Values.wallet.endpoints.default.path }}/check/readiness + port: {{ .Values.wallet.endpoints.default.port }} + initialDelaySeconds: {{ .Values.wallet.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.wallet.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.wallet.readinessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.wallet.readinessProbe.failureThreshold }} + successThreshold: {{ .Values.wallet.readinessProbe.successThreshold }} + {{- end }} + resources: + {{- toYaml .Values.wallet.resources | nindent 12 }} + env: + {{- if .Values.wallet.debug.enabled }} + - name: "JAVA_TOOL_OPTIONS" + {{- if .Values.wallet.debug.suspendOnStart }} + value: >- + {{ printf "%s-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=%v" (ternary "-XX:UseSVE=0 " "" .Values.wallet.useSVE) .Values.wallet.debug.port}} + {{- else }} + value: >- + {{ printf "%s-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=%v" (ternary "-XX:UseSVE=0 " "" .Values.wallet.useSVE) .Values.wallet.debug.port}} + {{- end }} + {{- end }} + {{- range $key, $value := .Values.wallet.envValueFrom }} + - name: {{ $key | quote }} + valueFrom: + {{- tpl (toYaml $value) $ | nindent 16 }} + {{- end }} + {{- range $key, $value := .Values.wallet.env }} + - name: {{ $key | quote }} + value: {{ $value | quote }} + {{- end }} + envFrom: + - configMapRef: + name: {{ $fullName }}-config + - configMapRef: + name: {{ $fullName }}-datasource-config + - secretRef: + name: {{ $fullName }}-datasource-credentials + {{- if .Values.wallet.superuser.createSecret }} + - secretRef: + name: {{ $fullName }}-superuser-credentials + {{- end }} + {{- if and (or .Values.wallet.envSecretNames .Values.wallet.envConfigMapNames) (or (gt (len .Values.wallet.envSecretNames) 0) (gt (len .Values.wallet.envConfigMapNames) 0)) }} + {{- range $value := .Values.wallet.envSecretNames }} + - secretRef: + name: {{ $value | quote }} + {{- end }} + {{- range $value := .Values.wallet.envConfigMapNames }} + - configMapRef: + name: {{ printf "%s-%s" $fullName $value | quote }} + {{- end }} + {{- end }} + volumeMounts: + {{- if .Values.customCaCerts }} + - name: custom-cacerts + mountPath: /opt/java/openjdk/lib/security/cacerts + subPath: cacerts + {{- end }} + - name: "tmp" + mountPath: "/tmp" + volumes: + - name: "configuration" + configMap: + {{- if .Values.customCaCerts }} + - name: custom-cacertificates + configMap: + name: {{ include "wallet.fullname" . }}-custom-cacerts + defaultMode: 0400 + - name: custom-cacerts + emptyDir: + sizeLimit: 1Mi + {{- end }} + - name: "tmp" + emptyDir: { } + {{- with .Values.wallet.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.wallet.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.wallet.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/charts/wallet/templates/hpa.yaml b/charts/wallet/templates/hpa.yaml new file mode 100644 index 000000000..fbb75d189 --- /dev/null +++ b/charts/wallet/templates/hpa.yaml @@ -0,0 +1,50 @@ +################################################################################# +# Copyright (c) 2025 Cofinity-X +# Copyright (c) 2025 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 +################################################################################# + +{{ if .Values.wallet.autoscaling.enabled }} +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "wallet.fullname" . }} + labels: + {{- include "wallet.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "wallet.fullname" . }} + minReplicas: {{ .Values.wallet.autoscaling.minReplicas }} + maxReplicas: {{ .Values.wallet.autoscaling.maxReplicas }} + metrics: + {{- if .Values.wallet.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + target: + averageUtilization: {{ .Values.wallet.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.wallet.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + target: + averageUtilization: {{ .Values.wallet.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/charts/wallet/templates/ingress.yaml b/charts/wallet/templates/ingress.yaml new file mode 100644 index 000000000..0822306b6 --- /dev/null +++ b/charts/wallet/templates/ingress.yaml @@ -0,0 +1,98 @@ +################################################################################# +# Copyright (c) 2025 Cofinity-X +# Copyright (c) 2025 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 +################################################################################# + +{{ $fullName := include "wallet.fullname" . }} +{{- $controlLabels := include "wallet.server.labels" . }} +{{- $controlEdcEndpoints := .Values.wallet.endpoints }} +{{- $gitVersion := .Capabilities.KubeVersion.GitVersion }} +{{- $namespace := .Release.Namespace }} + +{{- range .Values.wallet.ingresses }} +{{- if and .enabled .endpoints }} +{{- $controlIngressName := printf "%s-%s" $fullName .hostname }} +{{- $annotations := .annotations | default dict }} + +{{- if semverCompare ">=1.19-0" $gitVersion }} +apiVersion: networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" $gitVersion }} +apiVersion: networking.k8s.io/v1beta1 +{{- else }} +apiVersion: extensions/v1beta +{{- end }} +kind: Ingress +metadata: + name: {{ $controlIngressName }} + namespace: {{ $namespace | default "default" | quote }} + labels: + {{- $controlLabels | nindent 4 }} + annotations: + {{- if and .className (not (semverCompare ">=1.18-0" $gitVersion)) }} + {{- if not (hasKey $annotations "kubernetes.io/ingress.class") }} + {{- $_ := set $annotations "kubernetes.io/ingress.class" .className}} + {{- end }} + {{- end }} + {{- if .certManager }} + {{- if .certManager.issuer }} + {{- $_ := set $annotations "cert-manager.io/issuer" .certManager.issuer}} + {{- end }} + {{- if .certManager.clusterIssuer }} + {{- $_ := set $annotations "cert-manager.io/cluster-issuer" .certManager.clusterIssuer}} + {{- end }} + {{- end }} + {{- with $annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if and .className (semverCompare ">=1.18-0" $gitVersion) }} + ingressClassName: {{ .className }} + {{- end }} + {{- if .hostname }} + {{- if .tls.enabled }} + tls: + - hosts: + - {{ .hostname }} + {{- if .tls.secretName }} + secretName: {{ .tls.secretName }} + {{- else }} + secretName: {{ $controlIngressName }}-tls + {{- end }} + {{- end }} + rules: + - host: {{ .hostname }} + http: + paths: + {{- $ingressEdcEndpoints := .endpoints }} + {{- range $name, $mapping := $controlEdcEndpoints }} + {{- if (has $name $ingressEdcEndpoints) }} + - path: {{ $mapping.path }} + pathType: {{ $mapping.pathType | default "Prefix" }} + backend: + {{- if semverCompare ">=1.19-0" $gitVersion }} + service: + name: {{ $fullName }} + port: + number: {{ $mapping.port }} + {{- else }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} +{{- end }}{{- /* end: if .enabled */}} +{{- end }}{{- /* end: range .Values.ingresses */}} diff --git a/charts/wallet/templates/job-vault-init.yaml b/charts/wallet/templates/job-vault-init.yaml new file mode 100644 index 000000000..7f2ff1348 --- /dev/null +++ b/charts/wallet/templates/job-vault-init.yaml @@ -0,0 +1,87 @@ +################################################################################# +# Copyright (c) 2026 Construct-X +# +# 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 "wallet.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 "wallet.labels" . | nindent 8 }} + spec: + restartPolicy: OnFailure + serviceAccountName: {{ include "wallet.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.vault.hashicorp.init.privateKeyAlias }} + - name: PRIVATE_KEY_ALIAS + value: {{ . | quote }} + {{- end }} + {{- with .Values.vault.hashicorp.init.publicKeyAlias }} + - 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 }} diff --git a/charts/wallet/templates/secret-datasource.yaml b/charts/wallet/templates/secret-datasource.yaml new file mode 100644 index 000000000..1e3a18050 --- /dev/null +++ b/charts/wallet/templates/secret-datasource.yaml @@ -0,0 +1,42 @@ +################################################################################# +# Copyright (c) 2026 Construct-X +# +# 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 +################################################################################# + +{{ $fullName := .Values.fullnameOverride -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ $fullName }}-datasource-credentials + namespace: {{ .Release.Namespace | default "default" | quote }} + labels: + {{- include "wallet.labels" . | nindent 4 }} +type: Opaque +stringData: + + ################ + ## POSTGRESQL ## + ################ + + # default + EDC_DATASOURCE_DEFAULT_USER: {{ .Values.postgresql.auth.username | quote }} + EDC_DATASOURCE_DEFAULT_PASSWORD: {{ .Values.postgresql.auth.password | quote }} + + ########### + ## VAULT ## + ########### + EDC_VAULT_HASHICORP_TOKEN: {{ .Values.vault.hashicorp.token | required ".Values.vault.hashicorp.token is required" | quote }} diff --git a/charts/wallet/templates/secret-runtime.yaml b/charts/wallet/templates/secret-runtime.yaml new file mode 100644 index 000000000..0a9b73d9c --- /dev/null +++ b/charts/wallet/templates/secret-runtime.yaml @@ -0,0 +1,38 @@ +################################################################################# +# Copyright (c) 2026 Construct-X +# +# 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.wallet.superuser.createSecret -}} +{{- $fullName := .Values.fullnameOverride -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ $fullName }}-superuser-credentials + namespace: {{ .Release.Namespace | default "default" | quote }} + labels: + {{- include "wallet.labels" . | nindent 4 }} +type: Opaque +stringData: + ################ + ## Super-User ## + ################ + EDC_IH_API_SUPERUSER_ID: {{ .Values.wallet.superuser.id | quote }} + EDC_IH_API_KEY_SUPERUSER: {{ .Values.wallet.superuser.apiKey | quote }} + EDC_IH_API_SUPERUSER_PUBLIC_KEY_ALIAS: {{ .Values.wallet.superuser.publicKeyAlias | quote }} + EDC_IH_API_SUPERUSER_PRIVATE_KEY_ALIAS: {{ .Values.wallet.superuser.privateKeyAlias | quote }} +{{- end -}} \ No newline at end of file diff --git a/charts/wallet/templates/service.yaml b/charts/wallet/templates/service.yaml new file mode 100644 index 000000000..bbc5143c6 --- /dev/null +++ b/charts/wallet/templates/service.yaml @@ -0,0 +1,52 @@ +# +# Copyright (c) 2025 Cofinity-X +# Copyright (c) 2025 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 +# + +apiVersion: v1 +kind: Service +metadata: + name: {{ include "wallet.fullname" . }} + namespace: {{ .Release.Namespace | default "default" | quote }} + labels: + {{- include "wallet.server.labels" . | nindent 4 }} +spec: + type: {{ .Values.wallet.service.type }} + ports: + - port: {{ .Values.wallet.endpoints.default.port }} + targetPort: default + protocol: TCP + name: default + - port: {{ .Values.wallet.endpoints.identity.port }} + targetPort: identity + protocol: TCP + name: identity + - port: {{ .Values.wallet.endpoints.credentials.port }} + targetPort: credentials + protocol: TCP + name: credentials + - port: {{ .Values.wallet.endpoints.did.port }} + targetPort: did + protocol: TCP + name: did + - port: {{ .Values.wallet.endpoints.sts.port }} + targetPort: sts + protocol: TCP + name: sts + selector: + {{- include "wallet.server.selectorLabels" . | nindent 4 }} diff --git a/charts/wallet/templates/serviceaccount.yaml b/charts/wallet/templates/serviceaccount.yaml new file mode 100644 index 000000000..d58012bd3 --- /dev/null +++ b/charts/wallet/templates/serviceaccount.yaml @@ -0,0 +1,33 @@ +################################################################################# +# Copyright (c) 2025 Cofinity-X +# Copyright (c) 2025 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 +################################################################################# + +{{ if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "wallet.serviceAccountName" . }} + labels: + {{- include "wallet.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automount }} +{{- end }} diff --git a/charts/wallet/templates/tests/test.yaml b/charts/wallet/templates/tests/test.yaml new file mode 100644 index 000000000..66d5f8236 --- /dev/null +++ b/charts/wallet/templates/tests/test.yaml @@ -0,0 +1,43 @@ +# +# Copyright (c) 2025 Cofinity-X +# Copyright (c) 2025 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 +# + +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "wallet.fullname" . }}-test" + labels: + {{- include "wallet.server.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test + "helm.sh/hook-delete-policy": {{ .Values.tests.hookDeletePolicy }} +spec: + containers: + - name: readiness + image: curlimages/curl + command: [ 'curl', '--fail' ] + args: [ '{{- printf "http://%s:%v%s/check/readiness" (include "wallet.fullname" $ ) $.Values.wallet.endpoints.default.port $.Values.wallet.endpoints.default.path -}}' ] + restartPolicy: Never + securityContext: + fsGroup: 101 # curl_group + runAsGroup: 101 # curl_group + runAsNonRoot: true + runAsUser: 100 # curl_user + seccompProfile: + type: RuntimeDefault diff --git a/charts/wallet/values.yaml b/charts/wallet/values.yaml new file mode 100644 index 000000000..a0d4cc79d --- /dev/null +++ b/charts/wallet/values.yaml @@ -0,0 +1,404 @@ +################################################################################# +# Copyright (c) 2026 Construct-X +# Copyright (c) 2025 Cofinity-X +# Copyright (c) 2025,2026 LKS Next +# Copyright (c) 2025 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 +################################################################################# + + +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# Controls whether the bundled sub-charts are installed alongside the wallet. +# Set to false to use externally managed PostgreSQL or Vault instances. +install: + postgresql: true + vault: true + +# This is to override the chart name. +fullnameOverride: "wallet" +nameOverride: "wallet" + +# This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ +imagePullSecrets: [] + +# -- Add custom ca certificates to the truststore +customCaCerts: {} + +wallet: + # This sets the container image more information can be found here: https://kubernetes.io/docs/concepts/containers/images/ + image: + repository: "ghcr.io/project-construct-x/wallet" + # This sets the pull policy for images. + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "0.17.0-1" + initContainers: [] + # This is for setting Kubernetes Labels to a Pod. + # For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + podLabels: {} + + # This is for setting Kubernetes Annotations to a Pod. + # For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + podAnnotations: {} + + # Disables SVE (Scalable Vector Extension) instructions via JAVA_TOOL_OPTIONS. + # Enable on nodes with SVE-capable CPUs if the JVM produces illegal instruction errors. + useSVE: false + + # Remote debugging via JDWP. Never enable in production environments. + debug: + enabled: false + # Port the JDWP agent listens on inside the container + port: 1045 + # If true, the JVM suspends on startup until a debugger connects + suspendOnStart: false + + # Public hostname of the wallet. Used to construct did:web URLs and ingress routing. + hostname: "wallet.staging.construct-x.net" + + # Super-user participant seeded on first startup by the super-user-seed-extension. + # The api key is stored in Vault under the alias derived from the participant id. + superuser: + # If true, a Kubernetes Secret is created from the values below and mounted via envFrom. + # Set to false to provide the secret externally and reference it via envSecretNames. + createSecret: true + id: admin + # API key for the super-user. Must follow the format base64().. + apiKey: YWRtaW4.adminKey + publicKeyAlias: admin#pubkey + privateKeyAlias: admin#privkey + # -- Whether web DIDs should be interpreted as HTTPS or HTTP + didweb: + https: true + + # Extra environment variables that will be pass onto deployment pods + env: {} + + # "valueFrom" environment variable references that will be added to deployment pods. Name is templated. + # ref: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#envvarsource-v1-core + envValueFrom: {} + # ENV_NAME: + # configMapKeyRef: + # name: configmap-name + # key: value_key + # secretKeyRef: + # name: secret-name + # key: value_key + + # [Kubernetes Secret Resource](https://kubernetes.io/docs/concepts/configuration/secret/) names to load environment variables from + envSecretNames: [] + # - first-secret + # - second-secret + + # [Kubernetes ConfigMap Resource](https://kubernetes.io/docs/concepts/configuration/configmap/) names to load environment variables from + envConfigMapNames: [] + # - first-config-map + # - second-config-map + + # This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ + livenessProbe: + # -- Whether to enable kubernetes [liveness-probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) + enabled: true + # -- seconds to wait before performing the first liveness check + initialDelaySeconds: 5 + # -- this fields specifies that kubernetes should perform a liveness check every 5 seconds + periodSeconds: 5 + # -- number of seconds after which the probe times out + timeoutSeconds: 5 + # -- when a probe fails kubernetes will try 6 times before giving up + failureThreshold: 6 + # -- number of consecutive successes for the probe to be considered successful after having failed + successThreshold: 1 + + readinessProbe: + # -- Whether to enable kubernetes [readiness-probes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) + enabled: true + # -- seconds to wait before performing the first readiness check + initialDelaySeconds: 5 + # -- this fields specifies that kubernetes should perform a readiness check every 5 seconds + periodSeconds: 5 + # -- number of seconds after which the probe times out + timeoutSeconds: 5 + # -- when a probe fails kubernetes will try 6 times before giving up + failureThreshold: 6 + # -- number of consecutive successes for the probe to be considered successful after having failed + successThreshold: 1 + + # -- endpoints of the wallet + endpoints: + # -- default api for health checks, should not be added to any ingress + default: + # -- port for incoming api calls + port: 8181 + # -- path for incoming api calls + path: /api + # -- management api, used by internal users, can be added to an ingress and must not be internet facing + identity: + # -- port for incoming api calls + port: 15151 + # -- path for incoming api calls + path: /api/identity + # -- authentication key, must be attached to each 'X-Api-Key' request header + authKeyAlias: "sup3r$3cr3t" + # -- DCP Presentation API endpoint + credentials: + # -- port for incoming api calls + port: 13131 + # -- path for incoming api calls + path: /api/credentials + # -- DID service endpoint. DID documents can be resolved from here. + did: + # -- port for incoming api calls + port: 80 + # -- path for incoming api calls + path: / + # -- STS Endpoint, used to obtain tokens + sts: + # -- port for incoming api calls + port: 9292 + # -- path for incoming api calls + path: /api/sts + + # This is for setting up a service more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/ + service: + # This sets the service type more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: ClusterIP + # Additional annotations to add to the Service resource + annotations: {} + + ## Ingress declaration to expose the network service. + ingresses: + ## Public / Internet facing Ingress for the Presentation API + - enabled: true + # -- The hostname to be used to precisely map incoming traffic onto the underlying network service + hostname: "wallet.staging.construct-x.net" + # -- Additional ingress annotations to add + annotations: + cert-manager.io/cluster-issuer: letsencrypt-staging + external-dns.alpha.kubernetes.io/hostname: "wallet.staging.construct-x.net" + external-dns.alpha.kubernetes.io/ttl: "300" + # -- EDC endpoints exposed by this ingress resource + endpoints: + - default + - credentials + - did + - sts + - identity + # -- Defines the [ingress class](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class) to use + className: "nginx" + # -- TLS [tls class](https://kubernetes.io/docs/concepts/services-networking/ingress/#tls) applied to the ingress resource + tls: + # -- Enables TLS on the ingress resource + enabled: true + # -- If present overwrites the default secret name + secretName: "wallet-tls" + ## Adds [cert-manager](https://cert-manager.io/docs/) annotations to the ingress resource + certManager: + # -- If preset enables certificate generation via cert-manager namespace scoped issuer + issuer: "" + # -- If preset enables certificate generation via cert-manager cluster-wide issuer + clusterIssuer: "letsencrypt-staging" + ## Ingress for the Identity API, should not be internet facing + - enabled: false + # -- The hostname to be used to precisely map incoming traffic onto the underlying network service + hostname: "wallet.staging.construct-x.net" + # -- Additional ingress annotations to add + annotations: {} + # -- EDC endpoints exposed by this ingress resource + endpoints: + - identity + - accounts + - version + # -- Defines the [ingress class](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class) to use + className: "nginx" + # -- TLS [tls class](https://kubernetes.io/docs/concepts/services-networking/ingress/#tls) applied to the ingress resource + tls: + # -- Enables TLS on the ingress resource + enabled: false + # -- If present overwrites the default secret name + secretName: "" + ## Adds [cert-manager](https://cert-manager.io/docs/) annotations to the ingress resource + certManager: + # -- If preset enables certificate generation via cert-manager namespace scoped issuer + issuer: "" + # -- If preset enables certificate generation via cert-manager cluster-wide issuer + clusterIssuer: "letsencrypt-staging" + + # Additional volumeMounts on the output Deployment definition. + volumeMounts: [] + # - name: foo + # mountPath: "/etc/foo" + # readOnly: true + + # Additional volumes on the output Deployment definition. + volumes: [] + # - name: foo + # secret: + # secretName: mysecret + # optional: false + + # -- [resource management](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/) for the container + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 250m + memory: 128Mi + + # This section is for setting up autoscaling more information can be found here: https://kubernetes.io/docs/concepts/workloads/autoscaling/ + # This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/ + replicaCount: 1 + autoscaling: + # -- Enables [horizontal pod autoscaling](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/) + enabled: false + # -- Minimal replicas if resource consumption falls below resource threshholds + minReplicas: 1 + # -- Maximum replicas if resource consumption exceeds resource threshholds + maxReplicas: 100 + # -- targetAverageUtilization of cpu provided to a pod + targetCPUUtilizationPercentage: 80 + # -- targetAverageUtilization of memory provided to a pod + targetMemoryUtilizationPercentage: 80 + + # [node selector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector) to constrain pods to nodes + nodeSelector: {} + # [tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) to configure preferred nodes + tolerations: [] + # [affinity](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity) to configure which nodes the pods can be scheduled on + affinity: {} + + # The [pod security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod) defines privilege and access control settings for a Pod within the deployment + podSecurityContext: + seccompProfile: + # -- Restrict a Container's Syscalls with seccomp + type: RuntimeDefault + # -- Runs all processes within a pod with a special uid + runAsUser: 10100 + # -- Processes within a pod will belong to this guid + runAsGroup: 10100 + # -- The owner for volumes and any files created within volumes will belong to this guid + fsGroup: 10100 + + # The [container security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container) defines privilege and access control settings for a Container within a pod + securityContext: + capabilities: + # -- Specifies which capabilities to drop to reduce syscall attack surface + drop: + - ALL + # -- Specifies which capabilities to add to issue specialized syscalls + add: [] + # -- Whether the root filesystem is mounted in read-only mode + readOnlyRootFilesystem: true + # -- Controls [Privilege Escalation](https://kubernetes.io/docs/concepts/security/pod-security-policy/#privilege-escalation) enabling setuid binaries changing the effective user ID + allowPrivilegeEscalation: false + # -- Requires the container to run without root privileges + runAsNonRoot: true + # -- The container's process will run with the specified uid + runAsUser: 10100 + +# This section builds out the service account more information can be found here: https://kubernetes.io/docs/concepts/security/service-accounts/ +serviceAccount: + # Specifies whether a service account should be created + create: true + # Automatically mount a ServiceAccount's API credentials? + automount: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +# -- Configurations for Helm tests +tests: + # -- Configure the hook-delete-policy for Helm tests + hookDeletePolicy: before-hook-creation,hook-succeeded + +postgresql: + image: + # -- workaround to use bitnamilegacy chart for version 15.5.x till committers align on new postgresql charts + repository: bitnamilegacy/postgresql + # -- workaround to use bitnamilegacy chart for version 15.5.x till committers align on new postgresql charts + tag: "16.4.0-debian-12-r9" + + # JDBC connection URL passed to the wallet runtime. + jdbcUrl: "jdbc:postgresql://{{ .Release.Name }}-postgresql:5432/wallet" + primary: + persistence: + # Persist primary node data across pod restarts. + enabled: true + resources: + limits: + cpu: 500m + memory: 1Gi + requests: + cpu: 250m + memory: 256Mi + readReplicas: + persistence: + enabled: false + resources: + limits: + cpu: 500m + memory: 1Gi + requests: + cpu: 250m + memory: 256Mi + auth: + # Name of the PostgreSQL database created on first start. Must match with postgresql.jdbcUrl path. + database: "wallet" + # PostgreSQL user that the wallet connects as. + username: "user" + # Password for the PostgreSQL user. Change before production use. + password: "password" + +vault: + injector: + enabled: false + server: + dev: + # Run Vault in dev mode. All data is stored in memory and lost on pod restart. + # Disable for production and configure a persistent storage backend instead. + enabled: true + # Root token used when dev mode is active. Must match vault.hashicorp.token. + devRootToken: "root" + # Optional post-start hook script executed inside the Vault container after startup. + # Can be used to initialise the KV engine or apply policies. Must be set externally. + postStart: + hashicorp: + # URL of the Vault instance reachable from within the cluster. + url: "http://{{ .Release.Name }}-vault:8200" + # Vault token used by the wallet at runtime to read and write secrets. + # If vault.server.dev.enabled is true vault.hashicorp.token match with vault.server.dev.devRootToken. + token: "root" + # Timeout in seconds for Vault HTTP requests. + timeout: 30 + healthCheck: + enabled: true + standbyOk: true + paths: + # Mount path used for all wallet secrets + secret: /v1/secret + # Health endpoint polled by the wallet and the vault-init job + health: /v1/sys/health + init: + # Whether to run the post-install vault-init job that seeds required secrets + enabled: true + # Vault alias under which the AES-256 encryption key is stored. + aesKeyAlias: "wallet-aes-key-alias" From 73d2a5eb8602d141a1231b60b509db58bd9cf498 Mon Sep 17 00:00:00 2001 From: Simon Bergerfurth Date: Thu, 4 Jun 2026 09:33:19 +0200 Subject: [PATCH 2/3] chore: update licence headers in helm chart --- charts/wallet/Chart.yaml | 2 +- charts/wallet/templates/configmap-datasource.yaml | 2 +- charts/wallet/templates/configmap-runtime.yaml | 2 +- charts/wallet/templates/configmap-vault-init.yaml | 2 +- charts/wallet/templates/deployment.yaml | 2 +- charts/wallet/templates/job-vault-init.yaml | 2 +- charts/wallet/templates/secret-datasource.yaml | 2 +- charts/wallet/templates/secret-runtime.yaml | 2 +- charts/wallet/values.yaml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/charts/wallet/Chart.yaml b/charts/wallet/Chart.yaml index 11f85ff57..f1dea1fcd 100644 --- a/charts/wallet/Chart.yaml +++ b/charts/wallet/Chart.yaml @@ -1,5 +1,5 @@ ################################################################################# -# Copyright (c) 2026 Construct-X +# Copyright (c) 2026 Zentralverband der Deutschen Elektro- und Informationstechnischen Handwerke (ZVEH) # Copyright (c) 2025 Cofinity-X # Copyright (c) 2025 Contributors to the Eclipse Foundation # diff --git a/charts/wallet/templates/configmap-datasource.yaml b/charts/wallet/templates/configmap-datasource.yaml index fd291c723..55586b9e5 100644 --- a/charts/wallet/templates/configmap-datasource.yaml +++ b/charts/wallet/templates/configmap-datasource.yaml @@ -1,5 +1,5 @@ ################################################################################# -# Copyright (c) 2026 Construct-X +# Copyright (c) 2026 Zentralverband der Deutschen Elektro- und Informationstechnischen Handwerke (ZVEH) # Copyright (c) 2025 Cofinity-X # Copyright (c) 2025 Contributors to the Eclipse Foundation # diff --git a/charts/wallet/templates/configmap-runtime.yaml b/charts/wallet/templates/configmap-runtime.yaml index 1fa738b71..73994839b 100644 --- a/charts/wallet/templates/configmap-runtime.yaml +++ b/charts/wallet/templates/configmap-runtime.yaml @@ -1,5 +1,5 @@ ################################################################################# -# Copyright (c) 2026 Construct-X +# Copyright (c) 2026 Zentralverband der Deutschen Elektro- und Informationstechnischen Handwerke (ZVEH) # Copyright (c) 2025 Cofinity-X # Copyright (c) 2025 Contributors to the Eclipse Foundation # diff --git a/charts/wallet/templates/configmap-vault-init.yaml b/charts/wallet/templates/configmap-vault-init.yaml index f9308ce3e..a2c9d9d82 100644 --- a/charts/wallet/templates/configmap-vault-init.yaml +++ b/charts/wallet/templates/configmap-vault-init.yaml @@ -1,5 +1,5 @@ ################################################################################# -# Copyright (c) 2026 Construct-X +# 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. diff --git a/charts/wallet/templates/deployment.yaml b/charts/wallet/templates/deployment.yaml index ef44e7c80..7d086f4e2 100644 --- a/charts/wallet/templates/deployment.yaml +++ b/charts/wallet/templates/deployment.yaml @@ -1,5 +1,5 @@ # -# Copyright (c) 2026 Construct-X +# Copyright (c) 2026 Zentralverband der Deutschen Elektro- und Informationstechnischen Handwerke (ZVEH) # Copyright (c) 2025 Cofinity-X # Copyright (c) 2025 LKS Next # Copyright (c) 2025 Contributors to the Eclipse Foundation diff --git a/charts/wallet/templates/job-vault-init.yaml b/charts/wallet/templates/job-vault-init.yaml index 7f2ff1348..59d7a6dc1 100644 --- a/charts/wallet/templates/job-vault-init.yaml +++ b/charts/wallet/templates/job-vault-init.yaml @@ -1,5 +1,5 @@ ################################################################################# -# Copyright (c) 2026 Construct-X +# 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. diff --git a/charts/wallet/templates/secret-datasource.yaml b/charts/wallet/templates/secret-datasource.yaml index 1e3a18050..cb17f231a 100644 --- a/charts/wallet/templates/secret-datasource.yaml +++ b/charts/wallet/templates/secret-datasource.yaml @@ -1,5 +1,5 @@ ################################################################################# -# Copyright (c) 2026 Construct-X +# 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. diff --git a/charts/wallet/templates/secret-runtime.yaml b/charts/wallet/templates/secret-runtime.yaml index 0a9b73d9c..46a080bd4 100644 --- a/charts/wallet/templates/secret-runtime.yaml +++ b/charts/wallet/templates/secret-runtime.yaml @@ -1,5 +1,5 @@ ################################################################################# -# Copyright (c) 2026 Construct-X +# 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. diff --git a/charts/wallet/values.yaml b/charts/wallet/values.yaml index a0d4cc79d..bd53ac79f 100644 --- a/charts/wallet/values.yaml +++ b/charts/wallet/values.yaml @@ -1,5 +1,5 @@ ################################################################################# -# Copyright (c) 2026 Construct-X +# Copyright (c) 2026 Zentralverband der Deutschen Elektro- und Informationstechnischen Handwerke (ZVEH) # Copyright (c) 2025 Cofinity-X # Copyright (c) 2025,2026 LKS Next # Copyright (c) 2025 Contributors to the Eclipse Foundation From 11c34c154c8fff7a4770c52af75be9408e0c3aa5 Mon Sep 17 00:00:00 2001 From: Simon Bergerfurth Date: Thu, 4 Jun 2026 09:39:19 +0200 Subject: [PATCH 3/3] chore: add Tractus-X chart reference to NOTICE --- NOTICE.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NOTICE.md b/NOTICE.md index 2794aac86..581975d0e 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -34,6 +34,8 @@ Please refer to the [DEPENDENCIES](https://eclipse-edc.github.io/IdentityHub/DEP Beyond that, the construct-x wallet repository also includes the super-user-seed-extension as provided [here](https://github.com/FraunhoferISST/super-user-seed-extension) as a submodule. +The Constuct-X wallet Helm charts are based on [Tractus-X IdentityHub Helm charts](https://github.com/eclipse-tractusx/tractusx-identityhub). + ## Cryptography Content may contain encryption software. The country in which you are currently may have restrictions on the import,