From e399a5fa37c6501bad7ca4e1826e5839c334929a Mon Sep 17 00:00:00 2001 From: Noah Schatz Date: Wed, 13 May 2026 22:27:32 -0400 Subject: [PATCH 1/4] feat(01-03): add packaging/bridgelink.spec with SHA-256 file digest macros (#93) - New top-level packaging/ directory for RPM spec. - %global _binary_filedigest_algorithm 8 and _source_filedigest_algorithm 8 declared inline so cpio payload uses SHA-256 digests (FIPS-compatible). - Name=bridgelink, Version=26.3.1, BuildArch=noarch, Requires java-17-openjdk-headless. - /opt/bridgelink layout preserves server/setup/ contents under bridgelink/ archive root. - %changelog records initial FIPS packaging. Refs: SEC-01, Phase 1 Wave 3 (GH #93). --- packaging/bridgelink.spec | 40 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 packaging/bridgelink.spec diff --git a/packaging/bridgelink.spec b/packaging/bridgelink.spec new file mode 100644 index 000000000..9d0ad35a6 --- /dev/null +++ b/packaging/bridgelink.spec @@ -0,0 +1,40 @@ +# Copyright (c) 2026 Innovar Healthcare +# Licensed under the MPL-1.1. +# BridgeLink RPM spec — FIPS-compatible (SHA-256 file digests). Closes #93. See packaging/README.md. + +%global _binary_filedigest_algorithm 8 +%global _source_filedigest_algorithm 8 +%global _binary_payload_flags 0x1 + +Name: bridgelink +Version: 26.3.1 +Release: 1%{?dist} +Summary: BridgeLink healthcare integration engine +License: MPL-1.1 +URL: https://github.com/Innovar-Healthcare/BridgeLink +Source0: bridgelink-%{version}.tar.gz +BuildArch: noarch +BuildRequires: tar +BuildRequires: gzip +Requires: java-17-openjdk-headless + +%description +BridgeLink is a fork of NextGen Connect (Mirth Connect) — a healthcare +integration engine maintained by Innovar Healthcare. This RPM lays down +the server installation tree under /opt/bridgelink. Service management +(systemd unit, start scripts) is intentionally out of scope for this +initial FIPS-digest packaging fix. + +%prep +%setup -q -n bridgelink + +%install +mkdir -p %{buildroot}/opt/bridgelink +cp -r * %{buildroot}/opt/bridgelink/ + +%files +/opt/bridgelink + +%changelog +* Wed May 13 2026 Innovar Healthcare - 26.3.1-1 +- Initial RPM packaging with SHA-256 file digests for FIPS compatibility (closes #93) From 9e16fc77c3e8f14a69024f6f8b547cb760d56164 Mon Sep 17 00:00:00 2001 From: Noah Schatz Date: Wed, 13 May 2026 22:28:03 -0400 Subject: [PATCH 2/4] docs(01-03): add packaging/README.md with FIPS RPM build and verification recipe (#93) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Docker-based AlmaLinux 9 build recipe (rpmbuild in a clean container). - FIPS digest verification command: rpm -qp --qf "FILEDIGESTALGO=%{FILEDIGESTALGO}\n" must return 8 (SHA-256). - GPG signing-key audit command and pre-merge gate description (no SHA-1 subkey bindings allowed — Assumption A4). - FIPS-mode docker install smoke recipe (fips-mode-setup --enable + dnf install). - Out-of-scope section references SEC-V2-01 (commons-httpclient / WebDAV). Refs: SEC-01, Phase 1 Wave 3 (GH #93). --- packaging/README.md | 90 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 packaging/README.md diff --git a/packaging/README.md b/packaging/README.md new file mode 100644 index 000000000..ce81295f2 --- /dev/null +++ b/packaging/README.md @@ -0,0 +1,90 @@ + + +# BridgeLink RPM Packaging + +This directory holds `bridgelink.spec`, the RPM spec for BridgeLink. It closes +issue [#93](https://github.com/Innovar-Healthcare/BridgeLink/issues/93): on +FIPS-mode RHEL 8/9 and AlmaLinux 9 hosts, RPMs built with the historical RPM +default (MD5 cpio file digests) are rejected by the kernel with `cpio: Digest +mismatch`. The spec declares `%global _binary_filedigest_algorithm 8` and +`%global _source_filedigest_algorithm 8` in the spec body itself (so the +build is reproducible regardless of `~/.rpmmacros` on the build host), which +selects SHA-256 (algorithm `8`) for both binary and source payload digests. + +Maintainer: Innovar Healthcare. + +Wiring `rpmbuild` into `.github/workflows/build_bridgelink.yml` is out of +scope for this milestone — see the "Out of scope" section below. + +## Build recipe (Docker, AlmaLinux 9) + +```bash +# 1. Produce the source tarball expected by Source0. CI emits bridgelink.tar.gz +# without a version suffix; rename it so rpmbuild's %setup macro finds it. +cp bridgelink.tar.gz bridgelink-26.3.1.tar.gz + +# 2. Build the RPM inside a clean AlmaLinux 9 container. +docker run --rm -v "$PWD":/work -w /work almalinux:9 bash -c ' + dnf install -y rpm-build rpmdevtools tar gzip && \ + rpmdev-setuptree && \ + cp bridgelink-26.3.1.tar.gz ~/rpmbuild/SOURCES/ && \ + cp packaging/bridgelink.spec ~/rpmbuild/SPECS/ && \ + rpmbuild -bb ~/rpmbuild/SPECS/bridgelink.spec && \ + cp ~/rpmbuild/RPMS/noarch/bridgelink-*.rpm /work/ +' +``` + +The output artifact is `bridgelink-26.3.1-1.el9.noarch.rpm` (or similar +distribution tag) in the repo root. + +## FIPS digest verification + +```bash +rpm -qp --qf "FILEDIGESTALGO=%{FILEDIGESTALGO}\n" bridgelink-26.3.1-1.*.noarch.rpm +``` + +Expected output: `FILEDIGESTALGO=8` (SHA-256). Reject any other value +(`1` = MD5). If you see `FILEDIGESTALGO=1` or no output, the `%global` +directives did not apply — inspect the `rpmbuild` log for `warning: +%global ignored` and confirm the spec at `packaging/bridgelink.spec` is +the one rpmbuild consumed. + +## GPG signing key audit + +```bash +gpg --list-packets /path/to/innovar-public-signing-key.asc | grep "hash algorithm" +``` + +Every line MUST show `hash algorithm: SHA-256` or stronger. Any `SHA-1` +or `MD5` line means the key has a SHA-1 subkey binding and the key MUST +be regenerated before signing FIPS-compatible RPMs — RHEL 9's GPG +verifier rejects signatures whose subkey bindings use SHA-1. This audit +is a hard pre-merge gate for issue #93. Coordinate with the Innovar +Healthcare release/security team to obtain the public key for inspection. + +## FIPS-mode install test + +```bash +docker run --rm --privileged -v "$PWD":/work almalinux:9 bash -c ' + fips-mode-setup --enable && \ + dnf install -y /work/bridgelink-26.3.1-1.noarch.rpm +' +``` + +Expected: install completes with no `cpio: Digest mismatch` error. +A `Requires: java-17-openjdk-headless` resolution warning in the default +container repo configuration is acceptable for this digest-only smoke +test; production installs should run against a repo that provides the +Java runtime. + +The one-shot RHEL 8 hardware install verification is performed +out-of-band per the milestone's accepted verification matrix. + +## Out of scope for this milestone + +- Wiring `rpmbuild` into `.github/workflows/` — follow-up. +- Service definition (systemd unit) — separate issue. +- WebDAV / commons-httpclient removal — tracked as SEC-V2-01. From 21e11a92046d5116f725f534a72888cf68888119 Mon Sep 17 00:00:00 2001 From: Noah Schatz Date: Wed, 13 May 2026 22:59:18 -0400 Subject: [PATCH 3/4] fix(93): correct License to MPL-2.0 in spec + README (CR-02) The repository root LICENSE file declares Mozilla Public License Version 2.0 (SPDX: MPL-2.0), but the RPM spec's License: field and the copyright header comments in both bridgelink.spec and packaging/README.md incorrectly stated MPL-1.1. Built RPMs would have advertised the wrong license to downstream consumers (rpm -qi bridgelink). For FIPS / regulated-deployment customers this is a publishable-license metadata defect. Correct to MPL-2.0 in all three locations. --- packaging/README.md | 2 +- packaging/bridgelink.spec | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packaging/README.md b/packaging/README.md index ce81295f2..c74ca1ced 100644 --- a/packaging/README.md +++ b/packaging/README.md @@ -1,6 +1,6 @@ # BridgeLink RPM Packaging diff --git a/packaging/bridgelink.spec b/packaging/bridgelink.spec index 9d0ad35a6..0944c0671 100644 --- a/packaging/bridgelink.spec +++ b/packaging/bridgelink.spec @@ -1,5 +1,5 @@ # Copyright (c) 2026 Innovar Healthcare -# Licensed under the MPL-1.1. +# Licensed under the MPL-2.0. # BridgeLink RPM spec — FIPS-compatible (SHA-256 file digests). Closes #93. See packaging/README.md. %global _binary_filedigest_algorithm 8 @@ -10,7 +10,7 @@ Name: bridgelink Version: 26.3.1 Release: 1%{?dist} Summary: BridgeLink healthcare integration engine -License: MPL-1.1 +License: MPL-2.0 URL: https://github.com/Innovar-Healthcare/BridgeLink Source0: bridgelink-%{version}.tar.gz BuildArch: noarch From fcdd30fcc0bfeed1412c232ca06201dd7f1926ad Mon Sep 17 00:00:00 2001 From: Noah Schatz Date: Wed, 13 May 2026 22:59:35 -0400 Subject: [PATCH 4/4] fix(93): add %defattr to RPM %files section (WR-07) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without an explicit %defattr(-,root,root,-) the file ownership and permissions in the resulting RPM depend on the build environment's umask and the staged files' attributes — not deterministic across build hosts. RHEL packaging guidelines recommend always declaring %defattr even though modern rpmbuild defaults to root-owned. %doc / %license entries are deferred until a real production tarball that includes README.md and LICENSE in its payload is available (currently the %install just copies %{buildroot}/opt/bridgelink). --- packaging/bridgelink.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/packaging/bridgelink.spec b/packaging/bridgelink.spec index 0944c0671..7bdc88c79 100644 --- a/packaging/bridgelink.spec +++ b/packaging/bridgelink.spec @@ -33,6 +33,7 @@ mkdir -p %{buildroot}/opt/bridgelink cp -r * %{buildroot}/opt/bridgelink/ %files +%defattr(-,root,root,-) /opt/bridgelink %changelog