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`: