From 41be361aa968e107746eecbb37e12cf407f2eb4a Mon Sep 17 00:00:00 2001 From: Espen Hagen <2492641+espenhgn@users.noreply.github.com> Date: Fri, 18 Sep 2026 13:39:42 +0200 Subject: [PATCH 1/3] added some info on HUNT cloud deployment --- README.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/README.md b/README.md index cb2597b..ea0885a 100644 --- a/README.md +++ b/README.md @@ -140,6 +140,40 @@ The intended final-demo topology is one client on Gefion, one on NextCloud, and +### Real-world TREs + +#### HUNT Cloud + +
+ +Network opening request forms containing the IP:port address of the server should be sent to HUNT Cloud support by the data space leader (https://docs.hdc.ntnu.no/administer-science/service-desk/lab-orders#network-opening). +The server must be reachable from the HUNT Cloud network, and the HUNT Cloud TRE must be able to reach the server. +The server host must allow out/inbound connections to HUNT Cloud on the corresponding port (TLS, 129.241.176.121:8002), configurable e.g., on AWS. +Client kits and dependencies must be installed on the HUNT Cloud, e.g.: + +```sh +conda create -n heimdall python=3.12 +conda activate heimdall +pip install nvflare==2.9.0 + +# fetch client kit files +gdown https://drive.google.com/uc?id=whatever +unzip site-1.zip +cd site-1/startup + +# check the connection to the server using credentials +openssl s_client -connect 16.170.143.132:8002 -servername 16.170.143.132 -CAfile rootCA.pem -cert client.crt -key client.key -alpn h2 + +# modiy /etc/hosts file on client site (if needed) +grep -q "server1" /etc/hosts || echo "16.170.143.132 server1" | sudo tee -a /etc/hosts; + +# change permissions and start the client +chmod +x *.sh +./startup/sub_start.sh --once +``` + +
+ ## Technical reference See the [documentation index](docs/README.md) for reference material, planning history, architecture proposals, and scaling evidence. From e896cdde9ed34aa164c05ae6bbb659f19a16f333 Mon Sep 17 00:00:00 2001 From: Vitalii Babenko Date: Fri, 18 Sep 2026 13:52:13 +0200 Subject: [PATCH 2/3] docs: move the HUNT Cloud notes into the cloud runbook and align them with the site scripts The README was rewritten as a landing page in #34, so the block no longer had a place there. It is now section 4 of docs/cloud_demo.md, linked from the README's "Adding a TRE" details, with these corrections: - start the site with scripts/start_site.sh, which also runs the mock TRE the executor queries; the bare sub_start.sh path in the snippet pointed at startup/startup/sub_start.sh - a kit packed for an unreachable name is fixed by start_site.sh's third argument, not by editing /etc/hosts for a server name the project does not use - kits move through kit_export/kit_import as elsewhere in the runbook; a Drive download stays as the fallback, with the private-key caveat - literal server and HUNT addresses replaced by and "egress address"; the firewall sentence now states the direction (inbound to the server's 8002 from HUNT) - typo "modiy" Sections 4 and 5 of the runbook renumbered to 5 and 6; nothing linked to their anchors. --- README.md | 2 +- docs/cloud_demo.md | 28 ++++++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e94a502..4576e96 100644 --- a/README.md +++ b/README.md @@ -150,7 +150,7 @@ scripts/start_site.sh .remote/ # mock TRE + FLARE client; Re-run `python data/generate.py` to re-split the synthetic cohort for the new site count. A new API style is one adapter class implementing the five primitives plus a registry entry; a different local variable name is one `local:` line in [`harmonisation/canonical.yaml`](harmonisation/canonical.yaml) (unlisted sites use the canonical name). -Intended final topology: one client on Gefion, one on NextCloud, server on Brev or AWS — [docs/cloud_demo.md](docs/cloud_demo.md). +Intended final topology: one client on Gefion, one on NextCloud, server on Brev or AWS — [docs/cloud_demo.md](docs/cloud_demo.md). A client on HUNT Cloud needs a network-opening request first: [runbook section 4](docs/cloud_demo.md#4-site-on-hunt-cloud-optional). ## Five Safes diff --git a/docs/cloud_demo.md b/docs/cloud_demo.md index 4b9c771..ee17684 100644 --- a/docs/cloud_demo.md +++ b/docs/cloud_demo.md @@ -55,7 +55,31 @@ sbatch --export=TRE_ID=gefion,KIT=$PWD/.remote/gefion scripts/slurm_site.sbatch Needs outbound TCP from the compute node to `:8002` (`nc -zv 8002`). If Gefion has no egress, run `gefion` on the laptop as a third terminal instead — the demo still shows three heterogeneous APIs behind one server. -## 4. Run the analyses (AWS) +## 4. Site on HUNT Cloud (optional) + +HUNT Cloud opens no outbound connection by default. The data space leader files a network-opening request with HUNT Cloud support ([lab orders → network opening](https://docs.hdc.ntnu.no/administer-science/service-desk/lab-orders#network-opening)) naming the address and port the client will dial: `:8002`, TLS. The security-group rule from section 1 already admits the connection on the server side; restrict it to HUNT Cloud's egress address once that is known. + +In the HUNT Cloud lab, the same flow as Gefion (the kit holds only certificates, so the host needs a checkout too): + +```sh +git clone https://github.com/collaborativebioinformatics/Bifrost.git && cd Bifrost +conda create -n heimdall python=3.12 && conda activate heimdall # or a venv as in section 3 +pip install -e ".[dev]" "nvflare==2.9.0" +scripts/kit_import.sh hunt # paste the kit exported in section 1 +scripts/start_site.sh hunt .remote/hunt # mock TRE + FLARE client, as in section 2 +``` + +If pasting into the lab terminal is impractical, move `flare/kits/hunt.tgz` through a restricted share instead (for Drive: `gdown `), then `tar -xzf hunt.tgz -C .remote`. The archive holds the client's private key: no open links, and delete the copy afterwards. + +Before starting, the handshake can be checked with the kit's own credentials from `.remote/hunt`: + +```sh +openssl s_client -connect :8002 -servername -CAfile startup/rootCA.pem -cert startup/client.crt -key startup/client.key -alpn h2 +``` + +If the kit was packed for a name the lab cannot resolve, pass the address it can reach as a third argument, `scripts/start_site.sh hunt .remote/hunt :8002`; that patches a copy of the kit rather than `/etc/hosts`. To run only the FLARE client, without the restart loop: `cd .remote/hunt && bash startup/sub_start.sh --once` (jobs then have no mock TRE to query). + +## 5. Run the analyses (AWS) ```sh cd ~/Bifrost @@ -67,7 +91,7 @@ cd ~/Bifrost Each run prints coverage (`2/3 sites, missing ['gefion']` while Gefion is not up), the verify table against ground truth and the overseer queue. Audit trails are on each client host in `audit//audit.jsonl`; server decisions in `server/out/release_log.jsonl` on AWS. -## 5. Stop +## 6. Stop Ctrl-C in each site terminal; on AWS `(cd flare/workspace/federated_apis/prod_00/$DNS && bash startup/stop_fl.sh)`. From 9dd1ce2d7976b66860f68cb96a6f77245204580b Mon Sep 17 00:00:00 2001 From: Vitalii Babenko Date: Fri, 18 Sep 2026 14:03:46 +0200 Subject: [PATCH 3/3] docs: create restricted-share extraction directory --- docs/cloud_demo.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/cloud_demo.md b/docs/cloud_demo.md index ee17684..39a47e3 100644 --- a/docs/cloud_demo.md +++ b/docs/cloud_demo.md @@ -69,7 +69,7 @@ scripts/kit_import.sh hunt # paste the kit exported in section 1 scripts/start_site.sh hunt .remote/hunt # mock TRE + FLARE client, as in section 2 ``` -If pasting into the lab terminal is impractical, move `flare/kits/hunt.tgz` through a restricted share instead (for Drive: `gdown `), then `tar -xzf hunt.tgz -C .remote`. The archive holds the client's private key: no open links, and delete the copy afterwards. +If pasting into the lab terminal is impractical, move `flare/kits/hunt.tgz` through a restricted share instead (for Drive: `gdown `), then `mkdir -p .remote && tar -xzf hunt.tgz -C .remote`. The archive holds the client's private key: no open links, and delete the copy afterwards. Before starting, the handshake can be checked with the kit's own credentials from `.remote/hunt`: