Skip to content

doc: build: signing: document signing key file resolution#3

Open
JPHutchins wants to merge 1 commit into
mainfrom
doc/mcuboot-signing-key-custody
Open

doc: build: signing: document signing key file resolution#3
JPHutchins wants to merge 1 commit into
mainfrom
doc/mcuboot-signing-key-custody

Conversation

@JPHutchins

@JPHutchins JPHutchins commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

What

Adds a Signing key files section to the Signing Binaries page documenting how the MCUboot signing key file (SB_CONFIG_BOOT_SIGNATURE_KEY_FILE) is located, and cross-references it from the Sysbuild images page where the shared key is introduced.

Why

The signing docs only said the bundled key is "the insecure default" and to "change this appropriately" — silent on where a custom key may live or how a relative path to it resolves. One SB_CONFIG_BOOT_SIGNATURE_KEY_FILE drives two images that resolve relative paths against different bases:

image symbol relative-path search order
application CONFIG_MCUBOOT_SIGNATURE_KEY_FILE APPLICATION_CONFIG_DIRWEST_TOPDIR
MCUboot CONFIG_BOOT_SIGNATURE_KEY_FILE APPLICATION_CONFIG_DIR → MCUboot module dir

so a bare relative path that one image can resolve is generally not resolvable by the other. The new section documents the string(CONFIGURE) expansion of the value, the per-image search order, and that an absolute path or a ${APP_DIR}-anchored path is the reliable choice — the latter keeps the key in the user-owned application and resolves identically for both images. ${APP_DIR} is the maintainer-recommended anchor (zephyr discussion zephyrproject-rtos#59063) but was previously undocumented.

References

Maintainer-sanctioned fix (the behavior the docs should state)

  • zephyr discussion #59063 — "Configuring custom bootloader signature key with sysbuild." Canonical dual-image custody Q&A; maintainer answer recommends SB_CONFIG_BOOT_SIGNATURE_KEY_FILE="${APP_DIR}/my_key.pem" in sysbuild.conf (or an absolute path). The ${APP_DIR} anchor is recommended here but documented nowhere.
  • mcuboot PR #2591 — "Support resolving relative key file path via WEST_TOPDIR" (closed unmerged, 2026-01-12). Maintainer (nordicjm): "Not acceptable … use sysbuild and use an escaped path e.g. ${APP_DIR}/my.pem." Establishes that the app-image/bootloader-image resolution asymmetry is by design, so the gap is a documentation gap, not a bug to fix in code.
  • zephyr issue #85270 — closed "not planned" (2025-02-06). Confirms the supported knob is the sysbuild-scope SB_CONFIG_BOOT_SIGNATURE_KEY_FILE (plus SB_CONFIG_BOOT_SIGNATURE_TYPE_*), not the per-image CONFIG_MCUBOOT_SIGNATURE_KEY_FILE.

In-tree source of truth (what the docs should describe)

Pinned at zephyr main 1cfe02062, mcuboot main 0fae892:

  • zephyr/share/sysbuild/cmake/modules/sysbuild_extensions.cmake — the single string(CONFIGURE …) expansion of the key value in sysbuild scope (where ${APP_DIR} = the main application and ${CMAKE_CURRENT_LIST_DIR} = the sysbuild module dir inside zephyr). This is why ${APP_DIR} works and ${CMAKE_CURRENT_LIST_DIR} silently resolves into the zephyr tree.
  • zephyr/cmake/mcuboot.cmake — application-image resolver: absolute → ${APPLICATION_CONFIG_DIR}${WEST_TOPDIR} (the WEST_TOPDIR fallback is flagged in-code as west sign backward-compat).
  • mcuboot/boot/zephyr/CMakeLists.txt — bootloader-image resolver: absolute → ${APPLICATION_CONFIG_DIR}${MCUBOOT_DIR} (no WEST_TOPDIR fallback — the deliberate asymmetry).
  • zephyr/share/sysbuild/images/bootloader/Kconfig — defines SB_CONFIG_BOOT_SIGNATURE_KEY_FILE (default points inside the mcuboot module).
  • zephyr/share/sysbuild/image_configurations/MAIN_image_default.cmake and zephyr/share/sysbuild/images/bootloader/CMakeLists.txt — propagate that one symbol to the app image (CONFIG_MCUBOOT_SIGNATURE_KEY_FILE) and the bootloader image (CONFIG_BOOT_SIGNATURE_KEY_FILE) respectively.

Docs pages with the gap (targets to amend)

  • Signing Binaries — only says the bundled key is "the insecure default"; silent on APPLICATION_CONFIG_DIR / WEST_TOPDIR / MCUBOOT_DIR, on string(CONFIGURE) expansion, and on the dual-image propagation.
  • west sign — documents only the app-side half ("relative to the west workspace topdir"); does not mention the bootloader image's different base.
  • sysbuild / images — confirms one SB_CONFIG_BOOT_SIGNATURE_KEY_FILE drives both images (and FILE_SUFFIX can split them) but says nothing about where the key may live or how relative paths resolve.

Downstream vendor guidance (corroborates the gap)

  • NCS bootloader_signature_keys — the clearest official statement anywhere: "Use only absolute paths" for SB_CONFIG_BOOT_SIGNATURE_KEY_FILE; set it in sysbuild.conf; store the private key outside the build directory. Downstream had to write this because upstream is silent.
  • DevZone relative-path / wrong-consumer friction (years of it): #113899 (${APPLICATION_CONFIG_DIR} → empty, confirmed SDK bug, sdk-nrf PR ARM: alignment problems in libc/newlib zephyrproject-rtos/zephyr#16894), #115651 (${APP_DIR} unexpanded → /keys/…), #118977 (set it on the child image, not the parent), #123846 (Nordic: it's a build-system coupling, not an MCUboot flaw), #124004 (nRF Desktop per-board APPLICATION_CONFIG_DIR pattern), #80629.

MCUboot resolution-logic context (for the "why now" framing)

  • mcuboot PR #2701 — multi-key support; carries forward the IS_ABSOLUTE → APPLICATION_CONFIG_DIR → MCUBOOT_DIR block verbatim. This is the resolution logic visible at mcuboot main HEAD.
  • mcuboot PR #2702 — public-only PEM support for getpub/verify (underpins the custody model without changing path resolution).
  • MCUboot v2.3.0 release notes (TrustedFirmware) — introduced APPLICATION_CONFIG_DIR-relative key resolution with string(CONFIGURE) escaping.

Caveat before citing: the v2.3.0 release date and PR zephyrproject-rtos#2701's merge date don't line up, so the APPLICATION_CONFIG_DIR alignment and the multi-key feature are most likely separate commits. The exact upstream commit that first introduced the APPLICATION_CONFIG_DIR branch (zephyr and mcuboot sides) was not pinned down — confirm with git log -p/git blame on a non-shallow clone before attributing it.

Further corroboration (additional trackers & third-party guidance)

  • zephyr discussion #56453 — relative key paths concatenated onto the wrong base (corroborating report).
  • zephyr issue #73066 (closed via PR #73390) — maintainer awareness of the broader sysbuild-vs-image relative-anchoring class of bug.
  • zephyr discussion #97181 — the encryption-key analog of this problem, still unanswered.
  • zephyr discussion #64532 — overriding SIGNING_SCRIPT for external / HSM signing; mcuboot issue #599 — HSM support.
  • More DevZone relative-path / wrong-consumer friction: #113221, #65235, #116215, #92584.
  • Third-party consensus (generate your own key, never ship the in-tree example keys): Foundries.io zephyr-mcuboot-keys, Hubble Zephyr DFU guide.

Provenance: GitHub PR/issue/discussion numbers and the official-doc statements are high-confidence; DevZone dates are inferred from the referenced NCS versions (paraphrase-grade).

Verification

  • Empirical: resolution behavior verified against an example-application workspace (zephyr main, mcuboot main, nrf52840dk/nrf52840, ECDSA-P256): bare relative → resolves into mcuboot (fails); ${CMAKE_CURRENT_LIST_DIR} → resolves into zephyr (fails); ${APP_DIR} → builds, key stays in app.
  • In-tree source of truth confirmed against this checkout: cmake/mcuboot.cmake, bootloader/mcuboot/boot/zephyr/CMakeLists.txt, share/sysbuild/cmake/modules/sysbuild_extensions.cmake, and propagation via share/sysbuild/image_configurations/MAIN_image_default.cmake and share/sysbuild/images/bootloader/CMakeLists.txt.
  • RST: heading underlines, :ref: / :kconfig:option: targets, and code-block conventions checked against existing docs. A full Sphinx build was not run locally (heavy); relying on the CI docs build.

The commit message currently carries a short Zephyr-style summary; the full reference list above will also go into the upstream commit message.

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings June 22, 2026 22:17

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Comment thread doc/build/signing/index.rst Outdated
Comment thread doc/build/signing/index.rst Outdated
Comment thread doc/build/signing/index.rst Outdated
Comment thread doc/build/signing/index.rst Outdated
@JPHutchins JPHutchins force-pushed the doc/mcuboot-signing-key-custody branch from 103e8eb to 468725d Compare June 22, 2026 22:28
Comment thread doc/build/signing/index.rst Outdated
Comment thread doc/build/signing/index.rst Outdated
Comment thread doc/build/signing/index.rst Outdated
Comment thread doc/build/sysbuild/images.rst Outdated
@JPHutchins JPHutchins force-pushed the doc/mcuboot-signing-key-custody branch from 468725d to f275391 Compare June 22, 2026 22:37
Comment thread doc/build/signing/index.rst Outdated
Comment thread doc/build/signing/index.rst Outdated
The signing docs only described SB_CONFIG_BOOT_SIGNATURE_KEY_FILE as
"the insecure default" key to "change this appropriately", with no
guidance on where the key file may live or how a relative path to it is
resolved.

A single SB_CONFIG_BOOT_SIGNATURE_KEY_FILE feeds two images that resolve
relative key paths against different bases: the application image
(CONFIG_MCUBOOT_SIGNATURE_KEY_FILE) against APPLICATION_CONFIG_DIR then
WEST_TOPDIR, and the MCUboot image (CONFIG_BOOT_SIGNATURE_KEY_FILE)
against APPLICATION_CONFIG_DIR then the MCUboot module directory. A key
referenced by a bare relative path that one image can resolve is
therefore not resolvable by the other.

Document this on the Signing Binaries page: the value is expanded with
string(CONFIGURE), the per-image relative-path search order, and the
need for either an absolute path or a ${APP_DIR}-anchored path (the only
relative form that resolves identically for both images and keeps the
key in the user-owned application). Cross-reference it from the sysbuild
images page where the shared signing key is introduced.

Signed-off-by: JP Hutchins <jp@intercreate.io>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@JPHutchins JPHutchins force-pushed the doc/mcuboot-signing-key-custody branch from f275391 to a80c0c0 Compare June 22, 2026 22:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants