From dc5c951714c007efecbd207d5dcdc17e9d694637 Mon Sep 17 00:00:00 2001
From: Paul Latzelsperger <43503240+paullatzelsperger@users.noreply.github.com>
Date: Fri, 4 Oct 2024 07:01:12 +0200
Subject: [PATCH] feat: add standalone STS component (#355)
* add standalone STS runtime (wip)
* fix IntelliJ deployment
* updated README
* terraform fmt
* format readme toc
* updated README
* fix ci
---
.github/workflows/run-e2e-tests.yml | 2 +-
.run/remote/IdentityHub PROVIDER.run.xml | 4 +-
README.md | 43 +++++-
deployment/consumer.tf | 19 ++-
deployment/modules/identity-hub/main.tf | 52 +++----
deployment/modules/identity-hub/variables.tf | 12 +-
deployment/modules/sts/main.tf | 150 +++++++++++++++++++
deployment/modules/sts/outputs.tf | 20 +++
deployment/modules/sts/variables.tf | 60 ++++++++
deployment/provider.tf | 37 ++++-
gradle/libs.versions.toml | 5 +-
launchers/identity-hub/build.gradle.kts | 4 +-
launchers/sts/build.gradle.kts | 43 ++++++
launchers/sts/src/main/docker/Dockerfile | 25 ++++
settings.gradle.kts | 1 +
15 files changed, 428 insertions(+), 49 deletions(-)
create mode 100644 deployment/modules/sts/main.tf
create mode 100644 deployment/modules/sts/outputs.tf
create mode 100644 deployment/modules/sts/variables.tf
create mode 100644 launchers/sts/build.gradle.kts
create mode 100644 launchers/sts/src/main/docker/Dockerfile
diff --git a/.github/workflows/run-e2e-tests.yml b/.github/workflows/run-e2e-tests.yml
index ea5690ef..d1e77dd0 100644
--- a/.github/workflows/run-e2e-tests.yml
+++ b/.github/workflows/run-e2e-tests.yml
@@ -65,7 +65,7 @@ jobs:
cluster_name: dcp-demo
- name: "Load runtime images into KinD"
- run: kind load docker-image controlplane:latest dataplane:latest identity-hub:latest catalog-server:latest -n dcp-demo
+ run: kind load docker-image controlplane:latest dataplane:latest identity-hub:latest catalog-server:latest sts:latest -n dcp-demo
- name: "Install nginx ingress controller"
run: |-
diff --git a/.run/remote/IdentityHub PROVIDER.run.xml b/.run/remote/IdentityHub PROVIDER.run.xml
index 6a617f80..3fbbad1b 100644
--- a/.run/remote/IdentityHub PROVIDER.run.xml
+++ b/.run/remote/IdentityHub PROVIDER.run.xml
@@ -4,10 +4,10 @@
-
+
-
+
diff --git a/README.md b/README.md
index 2454b4db..39d5bd2b 100644
--- a/README.md
+++ b/README.md
@@ -17,6 +17,7 @@
* [5.1 Build the runtime images](#51-build-the-runtime-images)
* [5.2 Create the K8S cluster](#52-create-the-k8s-cluster)
* [5.3 Seed the dataspace](#53-seed-the-dataspace)
+ * [5.4 Debugging MVD in Kubernetes](#54-debugging-mvd-in-kubernetes)
* [6. Differences between Kubernetes and IntelliJ](#6-differences-between-kubernetes-and-intellij)
* [6.1 In-memory databases](#61-in-memory-databases)
* [6.2 Memory-based secret vaults](#62-memory-based-secret-vaults)
@@ -276,10 +277,10 @@ documentation for more information.
```shell
# Create the cluster
-kind create cluster -n dcp-demo --config deployment/kind.config.yaml
+kind create cluster -n mvd --config deployment/kind.config.yaml
# Load docker images into KinD
-kind load docker-image controlplane:latest dataplane:latest identity-hub:latest catalog-server:latest -n dcp-demo
+kind load docker-image controlplane:latest dataplane:latest identity-hub:latest catalog-server:latest sts:latest -n mvd
# Deploy an NGINX ingress
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml
@@ -331,7 +332,7 @@ Once all the deployments are up-and-running, the seed script needs to be execute
output similar to this:
```shell
-❯ ./seed-k8s.sh
+./seed-k8s.sh
Seed data to "provider-qna" and "provider-manufacturing"
@@ -358,6 +359,35 @@ _the `node` warnings are harmless and can be ignored_
> Failing to run the seed script will leave the dataspace in an uninitialized state and cause all connector-to-connector
> communication to fail.
+### 5.4 Debugging MVD in Kubernetes
+
+All of MVD's runtime images come with remote JVM debugging enabled by default. This is configured by setting an
+environment variable
+
+```
+JAVA_TOOL_OPTIONS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address="
+```
+
+All runtimes use port **1044** for debugging, unless configured otherwise in terraform. The only thing left to do for
+you is to create a Kubernetes port-forwarding:
+
+```shell
+kubectl port-forward -n mvd service/consumer-controlplane 1044:1044
+```
+
+This assumes the default Kubernetes namespace `mvd`. Note that the port-forward targets a `service` to have it
+consistent across pod restarts, but targeting a specific pod is also possible. Please refer to the official
+documentation for details.
+
+The host port (the value after the `:`) is completely arbitrary, and should be altered if multiple runtimes are debugged
+in parallel.
+
+When creating a "Remote JVM Debug" run configuration in IntelliJ it is important to select the appropriate module
+classpath. Those are generally located in the `launchers/` directory.
+
+Please also refer to the [official IntelliJ tutorial](https://www.jetbrains.com/help/idea/tutorial-remote-debug.html) on
+how to do remote debugging.
+
## 6. Differences between Kubernetes and IntelliJ
The focus with the Kubernetes deployment is to achieve a "one-click-deployment" (don't count them, it's more than 1)
@@ -384,12 +414,13 @@ all secrets that need to be accessed by multiple components must be pre-populate
### 6.3 Embedded vs Remote STS
-While in the Kubernetes deployment the SecureTokenService is embedded into the IdentityHub runtime, in the IntelliJ
+While in the Kubernetes deployment the SecureTokenService (S)S is a stand-alone component, in the IntelliJ
deployment it is embedded into the controlplane. The reason for this is, that during seeding a participant context and
an STS Account is created. This includes a (generated) client secret, that gets stored in the vault.
-In the IntelliJ case that vault is isolated in IdentityHub, with no way to access it from the connector's controlplane.
-This makes it necessary that the STS be embedded in the controlplane directly.
+In the IntelliJ case that vault is purely in-memory and is isolated in IdentityHub, with no way to access it from the
+connector's controlplane. So the connector's controlplane and IdentityHub physically cannot share any secrets. To
+overcome this, STS is simply embedded in the controlplane directly.
In the Kubernetes deployment this limitation goes away, because a dedicated vault service (HashiCorp Vault) is used,
which is accessible from either component.
diff --git a/deployment/consumer.tf b/deployment/consumer.tf
index 89b348db..008a5f1d 100644
--- a/deployment/consumer.tf
+++ b/deployment/consumer.tf
@@ -26,7 +26,7 @@ module "consumer-connector" {
}
vault-url = "http://consumer-vault:8200"
namespace = kubernetes_namespace.ns.metadata.0.name
- sts-token-url = module.consumer-identityhub.sts-token-url
+ sts-token-url = "${module.consumer-sts.sts-token-url}/token"
}
# consumer identity hub
@@ -43,7 +43,22 @@ module "consumer-identityhub" {
password = "consumer"
url = "jdbc:postgresql://${module.consumer-postgres.database-url}/consumer"
}
- namespace = kubernetes_namespace.ns.metadata.0.name
+ namespace = kubernetes_namespace.ns.metadata.0.name
+ sts-accounts-api-url = module.consumer-sts.sts-accounts-url
+}
+
+# consumer standalone STS
+module "consumer-sts" {
+ depends_on = [module.consumer-vault]
+ source = "./modules/sts"
+ humanReadableName = "consumer-sts"
+ namespace = kubernetes_namespace.ns.metadata.0.name
+ database = {
+ user = "consumer"
+ password = "consumer"
+ url = "jdbc:postgresql://${module.consumer-postgres.database-url}/consumer"
+ }
+ vault-url = "http://consumer-vault:8200"
}
# consumer vault
diff --git a/deployment/modules/identity-hub/main.tf b/deployment/modules/identity-hub/main.tf
index 4bf9c4d3..191326bb 100644
--- a/deployment/modules/identity-hub/main.tf
+++ b/deployment/modules/identity-hub/main.tf
@@ -136,31 +136,33 @@ resource "kubernetes_config_map" "identityhub-config" {
data = {
# IdentityHub variables
- EDC_API_AUTH_KEY = "password"
- EDC_IH_IAM_ID = var.participantId
- EDC_IAM_DID_WEB_USE_HTTPS = false
- EDC_IH_IAM_PUBLICKEY_ALIAS = local.public-key-alias
- EDC_IH_API_SUPERUSER_KEY = var.ih_superuser_apikey
- WEB_HTTP_PORT = var.ports.web
- WEB_HTTP_PATH = "/api"
- WEB_HTTP_IDENTITY_PORT = var.ports.ih-identity-api
- WEB_HTTP_IDENTITY_PATH = "/api/identity"
- WEB_HTTP_PRESENTATION_PORT = var.ports.presentation-api
- WEB_HTTP_PRESENTATION_PATH = "/api/presentation"
- WEB_HTTP_DID_PORT = var.ports.ih-did
- WEB_HTTP_DID_PATH = "/"
- WEB_HTTP_STS_PORT = var.ports.sts-api
- WEB_HTTP_STS_PATH = "/api/sts"
- JAVA_TOOL_OPTIONS = "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=${var.ports.ih-debug}"
- EDC_IAM_STS_PRIVATEKEY_ALIAS = var.aliases.sts-private-key
- EDC_IAM_STS_PUBLICKEY_ID = var.aliases.sts-public-key-id
- EDC_MVD_CREDENTIALS_PATH = "/etc/credentials/"
- EDC_VAULT_HASHICORP_URL = var.vault-url
- EDC_VAULT_HASHICORP_TOKEN = var.vault-token
- EDC_DATASOURCE_DEFAULT_URL = var.database.url
- EDC_DATASOURCE_DEFAULT_USER = var.database.user
- EDC_DATASOURCE_DEFAULT_PASSWORD = var.database.password
- EDC_SQL_SCHEMA_AUTOCREATE = true
+ EDC_API_AUTH_KEY = "password"
+ EDC_IH_IAM_ID = var.participantId
+ EDC_IAM_DID_WEB_USE_HTTPS = false
+ EDC_IH_IAM_PUBLICKEY_ALIAS = local.public-key-alias
+ EDC_IH_API_SUPERUSER_KEY = var.ih_superuser_apikey
+ WEB_HTTP_PORT = var.ports.web
+ WEB_HTTP_PATH = "/api"
+ WEB_HTTP_IDENTITY_PORT = var.ports.ih-identity-api
+ WEB_HTTP_IDENTITY_PATH = "/api/identity"
+ WEB_HTTP_PRESENTATION_PORT = var.ports.presentation-api
+ WEB_HTTP_PRESENTATION_PATH = "/api/presentation"
+ WEB_HTTP_DID_PORT = var.ports.ih-did
+ WEB_HTTP_DID_PATH = "/"
+ WEB_HTTP_STS_PORT = var.ports.sts-api
+ WEB_HTTP_STS_PATH = "/api/sts"
+ JAVA_TOOL_OPTIONS = "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=${var.ports.ih-debug}"
+ EDC_IAM_STS_PRIVATEKEY_ALIAS = var.aliases.sts-private-key
+ EDC_IAM_STS_PUBLICKEY_ID = var.aliases.sts-public-key-id
+ EDC_MVD_CREDENTIALS_PATH = "/etc/credentials/"
+ EDC_VAULT_HASHICORP_URL = var.vault-url
+ EDC_VAULT_HASHICORP_TOKEN = var.vault-token
+ EDC_DATASOURCE_DEFAULT_URL = var.database.url
+ EDC_DATASOURCE_DEFAULT_USER = var.database.user
+ EDC_DATASOURCE_DEFAULT_PASSWORD = var.database.password
+ EDC_SQL_SCHEMA_AUTOCREATE = true
+ EDC_STS_ACCOUNT_API_URL = var.sts-accounts-api-url
+ EDC_STS_ACCOUNTS_API_AUTH_HEADER_VALUE = "password"
}
}
diff --git a/deployment/modules/identity-hub/variables.tf b/deployment/modules/identity-hub/variables.tf
index 461d1080..d9a930fd 100644
--- a/deployment/modules/identity-hub/variables.tf
+++ b/deployment/modules/identity-hub/variables.tf
@@ -48,7 +48,7 @@ variable "ports" {
default = {
web = 7080
debug = 1044
- ih-debug = 1045
+ ih-debug = 1044
ih-did = 7083
ih-identity-api = 7081
presentation-api = 7082
@@ -61,11 +61,6 @@ variable "credentials-dir" {
description = "JSON object containing the credentials to seed, sorted by human-readable participant name"
}
-variable "participant-list-file" {
- type = string
- default = "./assets/participants/participants.k8s.json"
-}
-
variable "ih_superuser_apikey" {
default = "c3VwZXItdXNlcg==.c3VwZXItc2VjcmV0LWtleQo="
description = "Management API Key for the Super-User. Defaults to 'base64(super-user).base64(super-secret-key)"
@@ -105,4 +100,9 @@ variable "database" {
user = string
password = string
})
+}
+
+variable "sts-accounts-api-url" {
+ description = "Base URL for the STS Accounts API"
+ type = string
}
\ No newline at end of file
diff --git a/deployment/modules/sts/main.tf b/deployment/modules/sts/main.tf
new file mode 100644
index 00000000..1f8abe6a
--- /dev/null
+++ b/deployment/modules/sts/main.tf
@@ -0,0 +1,150 @@
+#
+# Copyright (c) 2024 Metaform Systems, Inc.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Apache License, Version 2.0 which is available at
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Contributors:
+# Metaform Systems, Inc. - initial API and implementation
+#
+
+resource "kubernetes_deployment" "sts" {
+ metadata {
+ name = var.humanReadableName
+ namespace = var.namespace
+ labels = {
+ App = var.humanReadableName
+ }
+ }
+
+ spec {
+ replicas = 1
+ selector {
+ match_labels = {
+ App = var.humanReadableName
+ }
+ }
+ template {
+ metadata {
+ labels = {
+ App = var.humanReadableName
+ }
+ }
+ spec {
+ container {
+ image = "sts:latest"
+ name = "sts"
+ image_pull_policy = "Never"
+
+ env_from {
+ config_map_ref {
+ name = kubernetes_config_map.sts-config.metadata[0].name
+ }
+ }
+ port {
+ container_port = var.ports.accounts
+ name = "accounts-port"
+ }
+
+ port {
+ container_port = var.ports.sts
+ name = "sts-port"
+ }
+
+ # Uncomment this to assign (more) resources
+ # resources {
+ # limits = {
+ # cpu = "2"
+ # memory = "512Mi"
+ # }
+ # requests = {
+ # cpu = "250m"
+ # memory = "50Mi"
+ # }
+ # }
+
+ liveness_probe {
+ http_get {
+ path = "/internal/check/liveness"
+ port = var.ports.web
+ }
+ failure_threshold = 10
+ period_seconds = 5
+ timeout_seconds = 30
+ }
+
+ readiness_probe {
+ http_get {
+ path = "/internal/check/readiness"
+ port = var.ports.web
+ }
+ failure_threshold = 10
+ period_seconds = 5
+ timeout_seconds = 30
+ }
+
+ startup_probe {
+ http_get {
+ path = "/internal/check/startup"
+ port = var.ports.web
+ }
+ failure_threshold = 10
+ period_seconds = 5
+ timeout_seconds = 30
+ }
+ }
+ }
+ }
+ }
+}
+
+resource "kubernetes_config_map" "sts-config" {
+ metadata {
+ name = "${var.humanReadableName}-config"
+ namespace = var.namespace
+ }
+
+ ## Create databases for keycloak and MIW, create users and assign privileges
+ data = {
+ JAVA_TOOL_OPTIONS = "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=${var.ports.debug}"
+ WEB_HTTP_ACCOUNTS_PORT = var.ports.accounts
+ WEB_HTTP_ACCOUNTS_PATH = var.accounts-path
+ WEB_HTTP_PORT = var.ports.web
+ WEB_HTTP_PATH = "/internal"
+ WEB_HTTP_STS_PORT = var.ports.sts
+ WEB_HTTP_STS_PATH = var.sts-path
+ EDC_API_ACCOUNTS_KEY = "password"
+ EDC_DATASOURCE_DEFAULT_URL = var.database.url
+ EDC_DATASOURCE_DEFAULT_USER = var.database.user
+ EDC_DATASOURCE_DEFAULT_PASSWORD = var.database.password
+ EDC_SQL_SCHEMA_AUTOCREATE = true
+
+ EDC_VAULT_HASHICORP_URL = var.vault-url
+ EDC_VAULT_HASHICORP_TOKEN = var.vault-token
+ }
+}
+
+resource "kubernetes_service" "sts-service" {
+ metadata {
+ name = "${var.humanReadableName}-service"
+ namespace = var.namespace
+ }
+ spec {
+ selector = {
+ App = kubernetes_deployment.sts.spec.0.template.0.metadata[0].labels.App
+ }
+ port {
+ name = "accounts-port"
+ port = var.ports.accounts
+ target_port = var.ports.accounts
+ }
+ port {
+ name = "sts-port"
+ port = var.ports.sts
+ target_port = var.ports.sts
+ }
+ }
+}
diff --git a/deployment/modules/sts/outputs.tf b/deployment/modules/sts/outputs.tf
new file mode 100644
index 00000000..f17eb117
--- /dev/null
+++ b/deployment/modules/sts/outputs.tf
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2024 Metaform Systems, Inc.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Apache License, Version 2.0 which is available at
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Contributors:
+# Metaform Systems, Inc. - initial API and implementation
+#
+
+output "sts-accounts-url" {
+ value = "http://${kubernetes_service.sts-service.metadata.0.name}:${var.ports.accounts}${var.accounts-path}"
+}
+
+output "sts-token-url" {
+ value = "http://${kubernetes_service.sts-service.metadata.0.name}:${var.ports.sts}${var.sts-path}"
+}
diff --git a/deployment/modules/sts/variables.tf b/deployment/modules/sts/variables.tf
new file mode 100644
index 00000000..e06d8535
--- /dev/null
+++ b/deployment/modules/sts/variables.tf
@@ -0,0 +1,60 @@
+#
+# Copyright (c) 2024 Metaform Systems, Inc.
+#
+# This program and the accompanying materials are made available under the
+# terms of the Apache License, Version 2.0 which is available at
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Contributors:
+# Metaform Systems, Inc. - initial API and implementation
+#
+
+variable "humanReadableName" {
+ description = "Name for STS instance"
+}
+
+variable "namespace" {
+ description = "kubernetes namespace where the PG instance is deployed"
+}
+
+variable "ports" {
+ type = object({
+ web = number
+ accounts = number
+ sts = number
+ debug = number
+ })
+ default = {
+ web = 8080
+ accounts = 8081
+ sts = 8082
+ debug = 1046
+ }
+}
+
+variable "database" {
+ type = object({
+ url = string
+ user = string
+ password = string
+ })
+}
+
+variable "accounts-path" {
+ default = "/api"
+}
+
+variable "sts-path" {
+ default = "/api/sts"
+}
+
+variable "vault-url" {
+ type = string
+}
+
+variable "vault-token" {
+ type = string
+ default = "root"
+}
\ No newline at end of file
diff --git a/deployment/provider.tf b/deployment/provider.tf
index 66f5f744..4a36442f 100644
--- a/deployment/provider.tf
+++ b/deployment/provider.tf
@@ -27,7 +27,7 @@ module "provider-qna-connector" {
}
namespace = kubernetes_namespace.ns.metadata.0.name
vault-url = "http://provider-vault:8200"
- sts-token-url = module.provider-identityhub.sts-token-url
+ sts-token-url = "${module.provider-sts.sts-token-url}/token"
}
# Second provider connector "provider-manufacturing"
@@ -42,7 +42,7 @@ module "provider-manufacturing-connector" {
}
namespace = kubernetes_namespace.ns.metadata.0.name
vault-url = "http://provider-vault:8200"
- sts-token-url = module.provider-identityhub.sts-token-url
+ sts-token-url = "${module.provider-sts.sts-token-url}/token"
}
module "provider-identityhub" {
@@ -60,6 +60,21 @@ module "provider-identityhub" {
password = "identityhub"
url = "jdbc:postgresql://${module.provider-postgres.database-url}/identityhub"
}
+ sts-accounts-api-url = module.provider-sts.sts-accounts-url
+}
+
+# provider standalone STS
+module "provider-sts" {
+ depends_on = [module.provider-vault]
+ source = "./modules/sts"
+ humanReadableName = "provider-sts"
+ namespace = kubernetes_namespace.ns.metadata.0.name
+ database = {
+ user = "sts"
+ password = "sts"
+ url = "jdbc:postgresql://${module.provider-postgres.database-url}/sts"
+ }
+ vault-url = "http://provider-vault:8200"
}
# Catalog server runtime
@@ -69,7 +84,7 @@ module "provider-catalog-server" {
participantId = var.provider-did
namespace = kubernetes_namespace.ns.metadata.0.name
vault-url = "http://provider-vault:8200"
- sts-token-url = module.provider-identityhub.sts-token-url
+ sts-token-url = "${module.provider-sts.sts-token-url}/token"
database = {
user = "catalog_server"
@@ -93,7 +108,8 @@ module "provider-postgres" {
kubernetes_config_map.postgres-initdb-config-cs.metadata[0].name,
kubernetes_config_map.postgres-initdb-config-pqna.metadata[0].name,
kubernetes_config_map.postgres-initdb-config-pm.metadata[0].name,
- kubernetes_config_map.postgres-initdb-config-ih.metadata[0].name
+ kubernetes_config_map.postgres-initdb-config-ih.metadata[0].name,
+ kubernetes_config_map.postgres-initdb-config-sts.metadata[0].name
]
namespace = kubernetes_namespace.ns.metadata.0.name
}
@@ -153,7 +169,20 @@ resource "kubernetes_config_map" "postgres-initdb-config-ih" {
CREATE USER identityhub WITH ENCRYPTED PASSWORD 'identityhub' SUPERUSER;
CREATE DATABASE identityhub;
\c identityhub
+ EOT
+ }
+}
+resource "kubernetes_config_map" "postgres-initdb-config-sts" {
+ metadata {
+ name = "sts-initdb-config"
+ namespace = kubernetes_namespace.ns.metadata.0.name
+ }
+ data = {
+ "sts-initdb-config.sql" = <<-EOT
+ CREATE USER sts WITH ENCRYPTED PASSWORD 'sts' SUPERUSER;
+ CREATE DATABASE sts;
+ \c sts
EOT
}
}
\ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 845463e9..fa4ddf68 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -151,6 +151,7 @@ edc-sts-accountprovisioner = { module = "org.eclipse.edc:sts-account-provisioner
edc-sts-accountservice-local = { module = "org.eclipse.edc:sts-account-service-local", version.ref = "edc" }
edc-sts-accountservice-remote = { module = "org.eclipse.edc:sts-account-service-remote", version.ref = "edc" }
edc-sts-remote-client = { module = "org.eclipse.edc:identity-trust-sts-remote-client", version.ref = "edc" }
+edc-sts-api-accounts = { module = "org.eclipse.edc:identity-trust-sts-accounts-api", version.ref = "edc" }
# federated catalog modules
edc-fc-spi-crawler = { module = "org.eclipse.edc:crawler-spi", version.ref = "edc" }
@@ -196,7 +197,9 @@ sql-edc-dataplane = ["edc-sql-accesstokendata", "edc-sql-dataplane", "edc-sql-co
sql-ih = ["edc-sql-ih-credstore-sql", "edc-sql-ih-didstore-sql", "edc-sql-ih-keypairstore-sql", "edc-sql-ih-pcstore-sql", "edc-sql-ih-stsstore-sql", "edc-sql-core", "edc-sql-pool", "edc-sql-transactionlocal", "postgres"]
-sts = ["edc-sts-core", "edc-sts-api", "edc-sts-accountprovisioner", "edc-sts-spi", "edc-sts", "edc-sts-accountservice-local"]
+sql-sts = [ "edc-sql-ih-stsstore-sql", "edc-sql-core", "edc-sql-pool", "edc-sql-transactionlocal", "postgres"]
+
+sts = ["edc-sts-core", "edc-sts-api", "edc-sts-spi", "edc-sts"]
sql-fc = ["edc-fc-cache-sql"]
diff --git a/launchers/identity-hub/build.gradle.kts b/launchers/identity-hub/build.gradle.kts
index 6db86b88..f38b37b9 100644
--- a/launchers/identity-hub/build.gradle.kts
+++ b/launchers/identity-hub/build.gradle.kts
@@ -24,9 +24,9 @@ dependencies {
if (project.properties.getOrDefault("persistence", "false") == "true") {
runtimeOnly(libs.edc.vault.hashicorp)
runtimeOnly(libs.bundles.sql.ih)
- println("This runtime compiles with an internal STS, Hashicorp Vault and PostgreSQL. You will need properly configured Postgres and HCV instances.")
+ runtimeOnly(libs.edc.sts.accountservice.remote)
+ println("This runtime compiles with a remote STS, Hashicorp Vault and PostgreSQL. You will need properly configured STS, Postgres and HCV instances.")
}
- runtimeOnly(libs.bundles.sts)
runtimeOnly(project(":extensions:superuser-seed"))
runtimeOnly(libs.bundles.identity.api)
diff --git a/launchers/sts/build.gradle.kts b/launchers/sts/build.gradle.kts
new file mode 100644
index 00000000..0ce8ec83
--- /dev/null
+++ b/launchers/sts/build.gradle.kts
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2024 Metaform Systems, Inc.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Apache License, Version 2.0 which is available at
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Contributors:
+ * Metaform Systems, Inc. - initial API and implementation
+ *
+ */
+
+plugins {
+ `java-library`
+ id("application")
+ alias(libs.plugins.shadow)
+}
+
+
+dependencies {
+ runtimeOnly(libs.bundles.connector)
+ runtimeOnly(libs.bundles.sts)
+ runtimeOnly(libs.edc.sts.api.accounts)
+ runtimeOnly(libs.edc.api.version)
+ runtimeOnly(libs.bundles.sql.sts)
+ runtimeOnly(libs.edc.vault.hashicorp)
+}
+
+tasks.withType {
+ exclude("**/pom.properties", "**/pom.xml")
+ mergeServiceFiles()
+ archiveFileName.set("sts.jar")
+}
+
+application {
+ mainClass.set("org.eclipse.edc.boot.system.runtime.BaseRuntime")
+}
+
+edcBuild {
+ publish.set(false)
+}
\ No newline at end of file
diff --git a/launchers/sts/src/main/docker/Dockerfile b/launchers/sts/src/main/docker/Dockerfile
new file mode 100644
index 00000000..430aac15
--- /dev/null
+++ b/launchers/sts/src/main/docker/Dockerfile
@@ -0,0 +1,25 @@
+# -buster is required to have apt available
+FROM eclipse-temurin:23_37-jre-alpine
+
+# Optional JVM arguments, such as memory settings
+ARG JVM_ARGS=""
+ARG JAR
+
+RUN apk --no-cache add curl
+
+WORKDIR /app
+
+
+COPY ${JAR} sts.jar
+
+EXPOSE 8188
+
+ENV WEB_HTTP_PORT="8080"
+ENV WEB_HTTP_PATH="/api"
+
+HEALTHCHECK --interval=5s --timeout=5s --retries=10 CMD curl --fail http://localhost:8080/api/check/health
+
+# Use "exec" for graceful termination (SIGINT) to reach JVM.
+# ARG can not be used in ENTRYPOINT so storing value in an ENV variable
+ENV ENV_JVM_ARGS=$JVM_ARGS
+ENTRYPOINT [ "sh", "-c", "exec java $ENV_JVM_ARGS -jar sts.jar"]
\ No newline at end of file
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 2f3172a0..92deab4c 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -49,3 +49,4 @@ include(":launchers:controlplane")
include(":launchers:dataplane")
include(":launchers:runtime-embedded")
include(":launchers:catalog-server")
+include(":launchers:sts")