Static linking across GPLv2 and Apache-2.0 in a shipped appliance
Nimbus Health ships an on-premise imaging appliance to hospitals. Release 7.0 bundles five third-party components into one closed appliance image: ClearView (GPLv2-only), statically linked into the main binary; FastJPEG (Apache-2.0), also statically linked into that same binary; MetricAgent (AGPL-3.0), a separate process exposing an HTTP metrics endpoint that the appliance web UI polls, with that UI served to hospital staff over the hospital LAN; CryptoKit (LGPL-2.1), an unmodified shared object loaded dynamically by NimbusCore, Nimbus's proprietary code; and IconSet (CC BY 4.0), 60 PNG icons embedded in the UI. Nimbus modifies none of these components. Legal is asked to approve shipping 7.0 as a single image under a proprietary license with no source code and a standard EULA. Sales has already told a hospital that no GPL code is present because the appliance is used internally by the customer rather than distributed to the public.
1. Which component combination blocks the plan, and what are the realistic options?
Read the worked answer
The blocker is statically combining ClearView and FastJPEG in one binary. Apache-2.0 is compatible with GPLv3 but not with GPLv2: its patent-termination and indemnification terms are additional restrictions that GPLv2 section 6 forbids. Statically linking Apache-2.0 code with GPLv2-only code produces a combined work that cannot be distributed under GPLv2, and the Apache-2.0 terms cannot simply be dropped. Because Nimbus ships the image to hospitals, this is a present distribution problem.
Options, cheapest first:
- Replace FastJPEG with an MIT- or BSD-licensed decoder, keeping the binary closed apart from ClearView.
- Check whether ClearView is 'GPLv2 or later' or has a GPLv3 branch. GPLv3 is compatible with Apache-2.0 and resolves the conflict; GPLv2-only does not.
- Isolate FastJPEG in a separate process communicating through an arm's-length interface (files or sockets) so it is not a combined work. Document the reasoning; same installer does not equal separate program.
- Obtain a proprietary license or GPLv2 exception from all relevant copyright holders, which is slow and often impractical with many contributors.
Correct Sales: handing an appliance to a hospital is distribution. The customer's internal use does not exempt Nimbus from GPL obligations. A contractual statement that no GPL code is present would be false and would become a warranty problem.
2. Analyze MetricAgent's AGPL obligations given that it is a separate process but is reached through a UI served over the hospital network.
Read the worked answer
AGPL section 13 is the deciding issue, not the process boundary alone. Running MetricAgent as a separate process helps with the combined-work question, but the appliance UI is served to hospital staff over the network and polls MetricAgent. Those users interact with MetricAgent remotely over a network, so the source-offer obligation attaches to that deployment.
Two questions to keep separate:
- Combined work? If MetricAgent communicates only through its documented HTTP endpoint using ordinary data, with no linking, shared memory, or shared address space, it is plausibly a separate program. If Nimbus patches it, embeds it in a shared runtime, or links NimbusCore to its internals, that argument collapses and the combined work becomes AGPL.
- Network interaction? The UI is the user-facing surface. If it proxies or embeds MetricAgent output, treat users as interacting with MetricAgent.
Recommended posture: keep MetricAgent unmodified and strictly separate; do not link it; publish the exact version plus a written offer of Corresponding Source, or simply ship the source, which is cheaper to administer; if Nimbus needs to modify it, release those modifications or replace it with a permissively licensed metrics agent. Do not rely on the hospital LAN as a carve-out; section 13 does not exempt private networks.
3. Build the compliance checklist for shipping 7.0 once the linking conflict is resolved.
Read the worked answer
Ship/no-ship checklist for 7.0
- ClearView (GPLv2-only): include full license text, provide complete corresponding source or a valid written offer for ClearView and the combined work, include a warranty disclaimer, and ensure nothing in the EULA restricts the GPL permissions. The offer must remain valid for the required period.
- FastJPEG (Apache-2.0): preserve copyright, license, and NOTICE content; state any modifications (none here). Resolve the GPLv2 conflict before this checklist can pass; documentation cannot cure incompatibility.
- MetricAgent (AGPL-3.0): ship the license, identify the version, and provide Corresponding Source or a written offer to network users as analyzed above.
- CryptoKit (LGPL-2.1): dynamic linking with no modification is the simple path. Ship the LGPL text and notices and ensure the customer can replace the library; do not sign or otherwise prevent replacement. If Nimbus later modifies it, publish the modified library source.
- IconSet (CC BY 4.0): attribution for each icon set in an About/Licenses screen or documentation, with title, author, source, and license. Keep icons as ordinary files; do not apply DRM that restricts use.
- Process: generate the notice file as a build artifact, archive the source bundle with the release record, and have legal approve a component inventory rather than a blanket statement. The EULA then covers only NimbusCore and the permissive components.