Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 8 additions & 11 deletions docs/.github/workflows/deploy-docs.yml
Original file line number Diff line number Diff line change
@@ -1,29 +1,26 @@

name: Deploy Docs

on:
push:
branches:
# make sure this is the branch you are using
- main
pull_request:
branches:
- main

jobs:
deploy-gh-pages:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
# if your docs needs submodules, uncomment the following line
# submodules: true



- name: Setup Node.js
uses: actions/setup-node@v3
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 #v7.0.0
with:
node-version: 20
node-version: 24
cache: npm

- name: Install Deps
Expand All @@ -37,8 +34,8 @@ jobs:
> src/.vuepress/dist/.nojekyll

- name: Deploy Docs
uses: JamesIves/github-pages-deploy-action@v4
if: github.event_name == 'push'
uses: JamesIves/github-pages-deploy-action@d92aa235d04922e8f08b40ce78cc5442fcfbfa2f #v4.8.0
with:
# This is the branch where the docs are deployed to
branch: gh-pages
folder: src/.vuepress/dist
9,220 changes: 5,381 additions & 3,839 deletions docs/package-lock.json

Large diffs are not rendered by default.

28 changes: 14 additions & 14 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,21 @@
"test:watch": "vitest"
},
"devDependencies": {
"@vuepress/bundler-vite": "2.0.0-rc.26",
"@vuepress/plugin-markdown-image": "2.0.0-rc.121",
"@vuepress/plugin-markdown-math": "2.0.0-rc.121",
"@vuepress/plugin-markdown-tab": "2.0.0-rc.121",
"@vuepress/plugin-slimsearch": "2.0.0-rc.121",
"katex": "0.16.28",
"sass-embedded": "1.97.3",
"sass-loader": "16.0.7",
"tsx": "4.22.4",
"vitest": "4.0.18",
"vue": "3.5.28",
"vuepress": "2.0.0-rc.26",
"vuepress-theme-hope": "2.0.0-rc.102"
"@vuepress/bundler-vite": "2.0.0-rc.30",
"@vuepress/plugin-markdown-image": "2.0.0-rc.132",
"@vuepress/plugin-markdown-math": "2.0.0-rc.132",
"@vuepress/plugin-markdown-tab": "2.0.0-rc.132",
"@vuepress/plugin-slimsearch": "2.0.0-rc.130",
"katex": "0.16.38",
"sass-embedded": "1.100.0",
"sass-loader": "16.0.8",
"tsx": "4.23.5",
"vitest": "4.1.10",
"vue": "^3.5.40",
"vuepress": "2.0.0-rc.30",
"vuepress-theme-hope": "2.0.0-rc.107"
},
"optionalDependencies": {
"@rollup/rollup-linux-x64-gnu": "4.59.0"
"@rollup/rollup-linux-x64-gnu": "4.62.4"
}
}
4 changes: 2 additions & 2 deletions docs/src/.vuepress/components/OldVersions.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<template>
<div>
<h2>DSF v2</h2>
<h2>DSF 2</h2>
<ul>
<li v-for="v in v2" :key="v.tag"><a :href="'./v' + v.tag + '/'">{{ v.tag }}</a></li>
</ul>
<h2>DSF v1</h2>
<h2>DSF 1</h2>
<ul>
<li v-for="v in v1" :key="v.tag"><a :href="'./v' + v.tag + '/'">{{ v.tag }}</a></li>
</ul>
Expand Down
17 changes: 14 additions & 3 deletions docs/src/.vuepress/data/releases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,31 @@ export const releases: Record<string, Release> = {
bpe_proxy: { digest: 'sha256:c67da4a1720ea75a383764db2bf25619fe70f57773b1069029f5b49588eb1ecc' },
},
},
'2.1.1': {
tag: '2.1.1',
previousTag: '2.1.0',
images: {
fhir: { digest: 'sha256:TODO' },
fhir_proxy: { digest: 'sha256:TODO' },
bpe: { digest: 'sha256:TODO' },
bpe_proxy: { digest: 'sha256:TODO' },
},
},
};

// --- Version registry (single source of truth) ---
// Sidebar keys reference generator functions by name; mapped in theme.ts.
// Ordered newest-first.
export type SidebarKey = 'v2_latest' | 'v2_0_0' | 'v1_latest' | 'v1_gte_1_7' | 'v1_gte_1_5' | 'v1_gte_1_0';
export type SidebarKey = 'v2_latest' | 'v2_1_0' | 'v2_0_0' | 'v1_latest' | 'v1_gte_1_7' | 'v1_gte_1_5' | 'v1_gte_1_0';

export interface VersionEntry {
tag: string;
sidebar: SidebarKey;
}

export const allVersions: VersionEntry[] = [
{ tag: '2.1.0', sidebar: 'v2_latest' },
{ tag: '2.1.1', sidebar: 'v2_latest' },
{ tag: '2.1.0', sidebar: 'v2_1_0' },
{ tag: '2.0.2', sidebar: 'v2_0_0' },
{ tag: '2.0.1', sidebar: 'v2_0_0' },
{ tag: '2.0.0', sidebar: 'v2_0_0' },
Expand All @@ -58,7 +69,7 @@ export const allVersions: VersionEntry[] = [
{ tag: '1.0.0', sidebar: 'v1_gte_1_0' },
];

export const latestVersion = '2.1.0';
export const latestVersion = '2.1.1';

export function getReleaseFromPath(path: string): Release | undefined {
const versionMatch = path.match(/(?:^|\/)operations\/v(\d+\.\d+\.\d+)\//);
Expand Down
Binary file not shown.
Binary file not shown.
6 changes: 3 additions & 3 deletions docs/src/.vuepress/scripts/llms-index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,9 @@ export const sections: LlmsSection[] = [
"description": "Verifying the authenticity and integrity of DSF container images"
},
{
"title": "Hardening Measures",
"link": "operations/latest/hardening-measures.html",
"description": "Recommended hardening measures for a production deployment"
"title": "Security Advisories",
"link": "operations/latest/security-advisories.html",
"description": "Security advisories published with the latest release"
},
{
"title": "Upgrade from DSF v1",
Expand Down
89 changes: 88 additions & 1 deletion docs/src/.vuepress/sidebar/operations-v2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,94 @@ export function generate_v2_latest_sidebar() {
icon: "tool",
link: "./",
},
"release-notes", "install", "upgrade-from-2", "upgrade-from-1", "allowList-mgm", "allowlist-generator", "root-certificates", "passwords-secrets", "image-verification", "hardening-measures", {
"release-notes", "install", "upgrade-from-2", "upgrade-from-1", "allowList-mgm", "allowlist-generator", "root-certificates", "passwords-secrets", "image-verification", "security-advisories", {
text: "FHIR Reverse Proxy",
icon: "module",
prefix: "fhir-reverse-proxy/",
link: "fhir-reverse-proxy/",
children: [
{
icon: "config",
text: "Configuration",
link: "configuration",
}
]
},
{
text: "FHIR Server",
icon: "module",
prefix: "fhir/",
link: "fhir/",
children: [{
icon: "config",
text: "Configuration",
link: "configuration"
}, {
icon: "config",
text: "Access Control",
link: "access-control"
}, {
icon: "config",
text: "OpenID Connect",
link: "oidc"
}, {
icon: "config",
text: "Logging",
link: "logging"
}]
}, {
text: "BPE Reverse Proxy",
icon: "module",
prefix: "bpe-reverse-proxy/",
link: "bpe-reverse-proxy/",
children: [
{
icon: "config",
text: "Configuration",
link: "configuration",
}
]
}, {
text: "BPE Server",
icon: "module",
prefix: "bpe/",
link: "bpe/",
children: [{
icon: "config",
text: "Configuration",
link: "configuration"
}, {
icon: "config",
text: "Access Control",
link: "access-control"
}, {
icon: "config",
text: "OpenID Connect",
link: "oidc"
}, {
icon: "config",
text: "Logging",
link: "logging"
}, {
icon: "config",
text: "FHIR Client Connections",
link: "fhir-client-connections"
}]
},
{
text: "Install Plugins",
icon: "plugin",
link: "install-plugins"
}]
}

export function generate_v2_1_0_sidebar() {
return [{
text: "Get Started",
icon: "tool",
link: "./",
},
"release-notes", "install", "upgrade-from-2", "upgrade-from-1", "allowList-mgm", "allowlist-generator", "root-certificates", "passwords-secrets", "image-verification", "security-advisories", "hardening-measures", {
text: "FHIR Reverse Proxy",
icon: "module",
prefix: "fhir-reverse-proxy/",
Expand Down
3 changes: 2 additions & 1 deletion docs/src/.vuepress/theme.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { slimsearchPlugin } from "@vuepress/plugin-slimsearch";
import { hopeTheme } from "vuepress-theme-hope";
import { generate_v1_latest_sidebar, generate_v1_gt_eq_1_7_0_sidebar, generate_v1_gt_eq_1_5_0_sidebar, generate_v1_gt_eq_1_0_0_sidebar } from "./sidebar/operations-v1";
import { generate_v2_0_0_sidebar, generate_v2_latest_sidebar } from "./sidebar/operations-v2";
import { generate_v2_0_0_sidebar, generate_v2_1_0_sidebar, generate_v2_latest_sidebar } from "./sidebar/operations-v2";
import { allVersions, latestVersion, type SidebarKey } from "./data/releases";

const sidebarGenerators: Record<SidebarKey, () => any[]> = {
v2_latest: generate_v2_latest_sidebar,
v2_1_0: generate_v2_1_0_sidebar,
v2_0_0: generate_v2_0_0_sidebar,
v1_latest: generate_v1_latest_sidebar,
v1_gte_1_7: generate_v1_gt_eq_1_7_0_sidebar,
Expand Down
2 changes: 1 addition & 1 deletion docs/src/news/fhir-devdays-2025/index.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<meta http-equiv="refresh" content="0;url=/posts/2025-05-07-fhir-devdays-2025.html">

# FHIR DevDays 2025
The DSF Team will be attending **FHIR DevDays 2025** from **June 3rd to 6th** in **Amsterdam**! The DevDays is the world’s leading event focused on HL7® FHIR® (Fast Healthcare Interoperability Resources). It’s dedicated to helping participants build expertise and accelerate the global implementation of FHIR standards. We’re excited to be speaking at the event and sharing insights from our work!
The DSF Team will be attending **FHIR DevDays 2025** from **June 3rd to 6th** in **Amsterdam**! The DevDays is the world’s leading event focused on HL7 FHIR (Fast Healthcare Interoperability Resources). It’s dedicated to helping participants build expertise and accelerate the global implementation of FHIR standards. We’re excited to be speaking at the event and sharing insights from our work!

![FHIR DevDays2025](/photos/news/Devdays-world.png)

Expand Down
2 changes: 1 addition & 1 deletion docs/src/operations/latest
2 changes: 1 addition & 1 deletion docs/src/operations/v2.1.0/fhir/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ icon: module

## Purpose

The **DSF FHIR Server** exposes the HL7® FHIR® R4 REST API that other DSF instances communicate with. It stores and serves the resources required to coordinate distributed business processes — such as `Task`, `ActivityDefinition`, `Organization`, `Endpoint`, and project-specific data resources — and enforces access control on every interaction. Together with the [FHIR Reverse Proxy](../fhir-reverse-proxy/) it forms the externally reachable component of a DSF instance.
The **DSF FHIR Server** exposes the HL7 FHIR R4 REST API that other DSF instances communicate with. It stores and serves the resources required to coordinate distributed business processes — such as `Task`, `ActivityDefinition`, `Organization`, `Endpoint`, and project-specific data resources — and enforces access control on every interaction. Together with the [FHIR Reverse Proxy](../fhir-reverse-proxy/) it forms the externally reachable component of a DSF instance.

## Docker Image

Expand Down
55 changes: 55 additions & 0 deletions docs/src/operations/v2.1.0/security-advisories.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
title: Security Advisories
icon: safe
---

# Security Advisories

The following security advisories have been published as part of the {{release.tag}} release.

## Missing Session Timeout for OIDC Sessions
CVE ID: [CVE-2026-40939](https://github.com/datasharingframework/dsf/security/advisories/GHSA-gj7p-595x-qwf5)
CVSS Score: Moderate, 6.8 / 10
CVSS: 4.0/AV:P/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N

### Affected Components
- DSF FHIR Server with enabled [OIDC authentication](fhir/oidc).
- DSF BPE Server with enabled [OIDC authentication](bpe/oidc).

### Summary
OIDC-authenticated sessions had no configured maximum inactivity timeout. Sessions persisted indefinitely after login, even after the OIDC access token expired.

### Impact
If a user logs in via OIDC and leaves their browser without explicitly logging out, the session remains valid indefinitely. Another person using the same browser can access the DSF UI with the previous user's permissions. This is a realistic threat in hospital environments with shared workstations.

Only affects OIDC browser sessions, not relevant for mTLS machine-to-machine communication.

### Fix (commits [f4ecb00](https://github.com/datasharingframework/dsf/commit/f4ecb00), [7d25fea](https://github.com/datasharingframework/dsf/commit/7d25fea))
- Added configurable session timeout via dev.dsf.server.auth.oidc.session.timeout (default: PT30M).
- Enabled logoutWhenIdTokenIsExpired(true) in OpenID configuration to tie session lifetime to token lifetime.
- Websocket sessions are now closed with VIOLATED_POLICY when credentials expire, prevents stale websocket connections from continuing to receive events after session timeout.


## Inverted Time Comparison in OIDC JWKS and Token Cache
CVE ID: [CVE-2026-40942](https://github.com/datasharingframework/dsf/security/advisories/GHSA-xmj9-7625-f634)
CVSS Score: Moderate, 6.3 / 10
CVSS: 4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N

### Affected Components
- DSF FHIR Server with enabled [bearer-token authentication](fhir/oidc) or [back-channel logout](fhir/oidc).
- DSF BPE Server with enabled [bearer-token authentication](bpe/oidc) or [back-channel logout](bpe/oidc).
- DSF BPE Server API v2 process plugins using [FHIR client connections](bpe/fhir-client-connections) with configured OIDC authentication.

### Summary
- The OIDC JWKS and Metadata Document caches used an inverted time comparison (isBefore instead of isAfter), causing the cache to never return cached values. Every incoming request triggered a fresh HTTP fetch of the OIDC Metadata Document and JWKS keys from the OIDC provider.
- The OIDC token cache for the [FHIR client connections](bpe/fhir-client-connections) used an inverted time comparison (isBefore instead of isAfter), causing the cache to never invalidate. Every incoming request returned the same OIDC token even if expired.

### Impact
- Performance: Every OIDC-authenticated request added network round-trips to the OIDC provider, increasing latency
- Reliability: Cached OIDC tokens become unusable after expiration and can only be invalidated by restart of the BPE.
If the OIDC provider is temporarily unreachable, all requests fail immediately instead of using cached keys
- Load: Unnecessary load on the OIDC provider, potentially causing rate limiting

### Fix (commits [31c2e97](https://github.com/datasharingframework/dsf/commit/31c2e97), [d3ca59b](https://github.com/datasharingframework/dsf/commit/d3ca59b))
- Fixed cache timeout comparison from isBefore to isAfter in BaseOidcClientWithCache (configuration and JWKS caches) and OidcClientWithCache (configuration, JWKS, and access token caches)
- Added configurable cache timeouts via dev.dsf.server.auth.oidc.provider.client.cache.timeout.configuration.resource and dev.dsf.server.auth.oidc.provider.client.cache.timeout.jwks.resource (default: PT1H)
34 changes: 34 additions & 0 deletions docs/src/operations/v2.1.1/allowList-mgm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
title: Allow List Management
icon: share
---
You can read all about the concept of Allow Lists [in our introduction](/explore/concepts/allow-list.md).

## Overview
To simplify the DSF Allow List Management we have built a portal for administration. The portal is managed by the GECKO Institute at Heilbronn University. You as an DSF administrator can create or update your Allow List information. The information you provide on this portal will be transferred to us and will be used to built Allow List bundles that get distributed to the communication partners of the distributed processes.

The DSF Allow List management tool uses client certificates for authentication. You can either use a personal client certificate or the client certificate from your DSF BPE, which needs to be added to your web-browsers certificate store.


## Prerequisites
1. Deployed DSF instance (test or production infrastructure)
1.1 If none exists yet, read [the installation guide](install)
2. Certificate
2.1 If none exists yet, read [the certificate requirements](install#client-server-certificates)
3. Organization identifier, shortest FQDN of your organizations website, e.g. `my-hospital.de`
4. FHIR endpoint URL, e.g. `https://dsf.my-hospital.de/fhir`
5. Contact details from a responsible person of your organization
6. Access to the E-Mail address from your organization for verification


## Start here
When you have fulfilled all the prerequisites, you can start managing your Allow Lists via the environment specific Allow List Management Tool:

- [**Test** infrastructure](https://allowlist-test.gecko.hs-heilbronn.de)
- [**Production** infrastructure](https://allowlist.gecko.hs-heilbronn.de)

We use different highlight colors for the DSF Allow List Management Tool: Green for the **Test** environment and blue for the **Production** infrastructure. To access the site, you have to authenticate yourself with a client certificate. Your web-browser will show a dialog to choose a valid certificate.

::: tip Ideas for improvement?
Have you found an error or is something unclear to you? Then please feel free to contact us on the <a href="https://mii.zulipchat.com/#narrow/stream/392426-Data-Sharing-Framework-.28DSF.29">MII-Zulip Channel</a> or write us at <a href="mailto:dsf-gecko@hs-heilbronn.de">dsf-gecko@hs-heilbronn.de</a>. Thank you very much!
:::
Loading
Loading