OpenBMC is an open source Linux distribution for baseboard management controllers (BMCs), the small computers inside servers, switches and storage appliances that handle power, sensors, consoles and firmware updates. It started as a Facebook project in 2014 and 2015, and became a Linux Foundation project in March 2018. To harden it, build without the features you do not need, sign images with your own key, turn off IPMI over LAN, replace the default credentials and certificate, and verify every setting through Redfish.
This guide goes one level deeper than our Redfish explainer and BMC lockdown guide, which covers the Redfish API itself, and our look at BMC firmware as a supply chain problem. Here we open the OpenBMC source tree and its documentation: the Yocto layers that build an image, the D-Bus services that run on the BMC, the signing classes that protect updates, the project's security reporting process and the build and runtime switches that make a production image safer. Every file name, option and default below comes from the OpenBMC repositories as fetched on 23 October 2026, the Yocto Project manuals, the OCP DC-SCM specification, NIST SP 800-193 and the June 2023 NSA and CISA BMC hardening guidance. Where a behaviour depends on a specific board or vendor build, we say so.
Key takeaways
- OpenBMC describes itself as "a Linux distribution for management controllers used in devices such as servers, top of rack switches or RAID appliances." It is built with Yocto and OpenEmbedded and runs systemd and D-Bus on the BMC.
- Facebook built the first version for its Wedge top of rack switch, starting with a 24 hour hackathon prototype, and published it on 10 March 2015. The Linux Foundation announced the community project on 19 March 2018, with IBM contributing its OpenBMC code base.
- Every board gets a machine layer (for example under
meta-aspeed,meta-nuvotonor a company's ownmeta-*layer). You pick the board with. setup <machine>and build withbitbake obmc-phosphor-image. - At runtime almost everything is a D-Bus object under
/xyz/openbmc_project/. Thebmcwebserver translates D-Bus into Redfish,ipmidandnetipmidserve IPMI,entity-managerdiscovers hardware andphosphor-user-managerhandles accounts. - Image signing is on by default, but a plain build signs with
OpenBMC.priv, a development key from a recipe whose description reads "Do not use this key to sign images." Production builds must set their ownSIGNING_KEYorSIGNING_PUBLIC_KEY. - Hardware rooted secure boot depends on the BMC chip. On ASPEED AST2600 boards the
socsec-signclass can sign the first stage loader, but it is off by default. - Security reports go in as draft GitHub security advisories against the affected repository. bmcweb, the Redfish server, has two published advisories: one from October 2022 fixed in 2.13 and one from April 2026 fixed in 3.0.0.
- OpenBMC "does not have a firewall," in the words of its own network security guide. Network isolation is your job, and the NSA and CISA guidance says the same about every BMC.
What is OpenBMC, who started it, and when did it join the Linux Foundation?
The short definition
The OpenBMC documentation repository opens with one sentence: the project "is a Linux Foundation project whose goal is to produce a customizable, open-source firmware stack for Baseboard Management Controllers (BMCs)." The main repository README is more concrete. It calls OpenBMC a Linux distribution for management controllers and lists its building blocks: Yocto, OpenEmbedded, systemd and D-Bus.
OpenBMC is not a single program but a whole embedded Linux system: a bootloader (U-Boot), a Linux kernel with BMC chip drivers, a C library, OpenSSL, a web server, an IPMI stack, a sensor framework, a user manager, a firmware updater and dozens of smaller daemons. A company that ships OpenBMC on its boards is shipping a distribution, with all the dependency tracking that implies.
Where it came from
Facebook's engineering blog post "Introducing OpenBMC: an open software framework for next-generation system management," published on 10 March 2015, tells the origin story. While building its Wedge top of rack switch, Facebook first left BMC software to its hardware partner, as was normal. Requirements kept changing, and coordination slowed everything down. At one of the company's hackathons, four engineers built their own BMC software, and in 24 hours had a minimal image with an SSH server, fan speed control, host power on and LED control. Eight months later that code, named OpenBMC, was in production on Wedge, and Facebook open sourced it. The facebook/openbmc repository on GitHub was created on 9 March 2015 and still describes itself as "an open software framework to build a complete Linux image for a Board Management Controller (BMC)."
In parallel, IBM developed its own OpenBMC code base for its server platforms. On 19 March 2018 the Linux Foundation's executive director announced that "IBM is providing their OpenBMC code base to The Linux Foundation," with support from Facebook, Google, Intel and Microsoft. The goal, in the post's words, was a stack "that will work across heterogeneous systems that include enterprise, HPC, telco, and cloud-scale data centers." The project charter on openbmc.org is dated 14 February 2018. Today the github.com/openbmc organisation hosts the Linux Foundation project, while the original Facebook tree continues as a separate repository.
How the project is governed
The main README points to a Technical Oversight Forum (TOF) that "guides the technical direction of the project," with members voted in by the community under published membership and voting rules in the docs repository. Code review happens in Gerrit, and the README explains the CI flow: member commits run through make check at the repository level, and then a full firmware image is built and booted in an arm QEMU model against the Robot Framework test suite in openbmc-test-automation. Commits from non members do not run CI automatically; a reviewer triggers it after looking at the change.
Releases
OpenBMC tags releases in the main repository. The v2.0 tag points at a commit dated 1 November 2017, 2.18.0 at a commit dated 30 May 2025 and 3.0.0 at a commit dated 15 May 2026, with 3.1.0-dev opened the day before. Most production users track master or a release branch with their own layers and patches, so a version number alone tells you little about what is inside a given BMC.
Timeline
| Date | Event | Source |
|---|---|---|
| 2014 | Facebook hackathon produces a 24 hour BMC prototype for the Wedge switch; production follows about eight months later | Facebook engineering blog, 10 Mar 2015 |
| 9 Mar 2015 | facebook/openbmc repository created on GitHub | GitHub API |
| 10 Mar 2015 | Facebook publishes "Introducing OpenBMC" and open sources the code | Engineering at Meta |
| 1 Nov 2017 | Commit tagged v2.0 in openbmc/openbmc | GitHub |
| 14 Feb 2018 | OpenBMC project charter dated | openbmc.org |
| 19 Mar 2018 | Linux Foundation announces the OpenBMC community project, with IBM contributing its code base | Linux Foundation blog |
| May 2018 | NIST SP 800-193, Platform Firmware Resiliency Guidelines, published | NIST CSRC |
| 11 Mar 2021 | OCP DC-SCM specification revision 1.0 | Open Compute Project |
| 19 Oct 2022 | bmcweb advisory GHSA-g3qc-375m-h66j (CVE-2022-2809) published; fixed in 2.13 | GitHub |
| 14 Jun 2023 | NSA and CISA publish "Harden Baseboard Management Controllers" | CISA |
| 30 May 2025 | Commit tagged 2.18.0 | GitHub |
| 21 Apr 2026 | bmcweb advisory GHSA-p3gc-68x5-g9w3 published; fixed in 3.0.0 | GitHub |
| 15 May 2026 | Commit tagged 3.0.0 | GitHub |
The 2014 hackathon date is inferred: the March 2015 post says production followed "eight months" after the prototype but gives no exact date.
How is OpenBMC built? Yocto, OpenEmbedded and machine layers
Yocto in two paragraphs
The Yocto Project's overview manual describes it as "an open source collaboration project that helps developers create custom Linux-based systems that are designed for embedded products regardless of the product's hardware architecture." Its build engine is BitBake, which reads recipes (.bb files) that say where to fetch source, how to patch, configure, compile and package it. OpenEmbedded Core supplies the base recipes and classes.
The idea that makes OpenBMC possible is the Yocto layer model. The manual calls it "a development model for embedded and IoT Linux creation" in which layers are repositories of related recipes and configuration. A layer can add recipes or change existing ones without copying them, using append files (.bbappend). The Yocto development manual is explicit: do not copy an entire recipe into your layer and edit it; use a .bbappend to override only what you need. Each layer has a conf/layer.conf that sets a BBFILE_PRIORITY, which decides which layer wins when two provide the same recipe.
The OpenBMC layer stack
The top of the openbmc/openbmc tree shows how this is applied. Alongside bitbake, meta (OpenEmbedded Core) and an upstream-layers directory with meta-openembedded, meta-arm and others, there are three kinds of OpenBMC layers:
| Layer type | Examples in the tree | What it holds |
|---|---|---|
| Core distribution | meta-phosphor | The openbmc-phosphor distro, the Phosphor daemons, image classes, signing logic, distro feature includes |
| BMC chip (SoC) support | meta-aspeed, meta-nuvoton, meta-hpe/meta-gxp | Kernel and U-Boot recipes for the chip, chip family includes such as ast2600.inc, ast2700.inc, npcm7xx.inc, npcm8xx.inc, gxp.inc |
| Company and board layers | meta-ibm, meta-facebook, meta-ampere, meta-quanta and about twenty more | Machine configurations, device trees, sensor and fan tables, entity-manager JSON, OEM features |
| Security extras | meta-security | Additional security tooling recipes |
A machine configuration file (for example meta-<company>/meta-<board>/conf/machine/<board>.conf) ties these together: it includes the SoC family file, chooses a flash layout, and pulls in board specific packages. The docs repository has a long tutorial, "add-new-system.md," for porting a new board, and the README warns that porting "is a non-trivial undertaking, ideally done with the assistance of schematics."
Building an image
The build steps in the README are short:
# Host packages on Ubuntu, from the openbmc README
sudo apt install git gcc g++ make file wget \
gawk diffstat bzip2 cpio chrpath zstd lz4
git clone https://github.com/openbmc/openbmc
cd openbmc
# With no argument, setup lists every supported machine
. setup
# Pick a machine (romulus is a long standing QEMU friendly target)
. setup romulus
# Build the default image
bitbake obmc-phosphor-image
Images land in tmp/deploy/images/<machine>/. Depending on the flash layout, the update tarball is obmc-phosphor-image-<machine>-<timestamp>.static.mtd.tar or .ubi.mtd.tar, and eMMC systems produce an ext4.mmc tarball.
Two Yocto commands are worth knowing before you change anything:
# Which layers are active, in which priority order
bitbake-layers show-layers
# Which bbappend files modify which recipes (useful when auditing a vendor tree)
bitbake-layers show-appends
Distro features: the build time switches
The meta-phosphor/conf/distro/include/ directory holds small include files that switch whole features on or off. The ones that matter for hardening are short enough to quote in full in spirit:
| Include file | Distro feature it sets | Effect, per the file |
|---|---|---|
phosphor-no-ipmi-rmcp.inc | phosphor-no-ipmi-rmcp | Builds without network IPMI (RMCP+) and marks the pam-ipmi module as a bad recommendation |
phosphor-no-root-login.inc | phosphor-no-root-login | Removes the allow-root-login image feature so root cannot log in over SSH and is not in privileged groups, then runs usermod --lock root |
phosphor-no-webui.inc | phosphor-no-webui | Builds without the web user interface |
phosphor-no-snmp.inc | phosphor-no-snmp | Builds without SNMP |
phosphor-production.inc | phosphor-production | A flag for "settings that may be more appropriate for production or deployment environments than development" |
phosphor-isolation.inc | isolate-bmc | Enables the BMC isolation feature for platforms that support it |
These map directly to the first advice in OpenBMC's network security guide: "Services which are not required should be disabled to limit the BMC's attack surface," preferably by configuring the recipes to "build the unwanted feature out of the BMC's firmware image."
SBOMs come with the build system
Because OpenBMC is a Yocto distribution, it inherits Yocto's software bill of materials tooling. The Yocto development manual says the OpenEmbedded build system "generates such information by default (by inheriting the create-spdx class in INHERIT_DISTRO)." Building an image produces an IMAGE-MACHINE.spdx.json file in tmp/deploy/images/MACHINE/, and bitbake <recipe> -c create_recipe_sbom produces one for a single recipe. Options such as SPDX_INCLUDE_SOURCES, SPDX_INCLUDE_KERNEL_CONFIG and SPDX_PACKAGE_SUPPLIER add detail.
For vulnerability matching, the current Yocto security manual describes an sbom-cve-check class enabled through a configuration fragment (OE_FRAGMENTS += "core/yocto/sbom-cve-check"). It maps each recipe name and version to the CVE database and writes reports such as <image>-<machine>.rootfs.sbom-cve-check.yocto.json, marking each CVE as Patched, Unpatched or Ignored. Fragment support depends on the Yocto release under your OpenBMC tree, and a distro can remove create-spdx, so look for the .spdx.json file after your first build rather than assuming it is there. This is the biggest practical difference from closed BMC firmware: the component list comes straight from the build that made the image.
What is the OpenBMC runtime architecture?
D-Bus as the backbone
Every OpenBMC service publishes its state as objects on the system D-Bus. Interfaces are defined in YAML in the phosphor-dbus-interfaces repository under the xyz/openbmc_project namespace, so a temperature sensor, a power supply, a firmware image and a user account all look like D-Bus objects with typed properties, methods and signals. External interfaces (Redfish, IPMI, the web UI) do not talk to hardware directly. They read and write those objects.
The piece that holds this together is the ObjectMapper. The docs describe the xyz.openbmc_project.ObjectMapper service as the way to find which service hosts a given object path and interface. A client that wants every sensor asks the mapper for the subtree under /xyz/openbmc_project/sensors and gets back the owning services and their interfaces.
You can explore this on a lab BMC (or the QEMU image) with busctl. These commands only read:
# List D-Bus services on the BMC
busctl list | grep xyz.openbmc_project
# Ask the ObjectMapper who owns a sensor path (example path from the OpenBMC docs)
busctl call xyz.openbmc_project.ObjectMapper \
/xyz/openbmc_project/object_mapper \
xyz.openbmc_project.ObjectMapper GetObject sas \
/xyz/openbmc_project/sensors/voltage/ps1_input_voltage 0
# Show the firmware images the code updater knows about
busctl tree xyz.openbmc_project.Software.BMC.Updater
The main services
| Service | Repository | Role |
|---|---|---|
| bmcweb | openbmc/bmcweb | The web server. Serves Redfish (a "DBus to Redfish translator"), the web UI, an optional Phosphor D-Bus REST API, and WebSockets for KVM, virtual media and the host serial console |
| webui-vue | openbmc/webui-vue | The browser user interface, served by bmcweb |
| ipmid | openbmc/phosphor-host-ipmid | The IPMI command router. Receives commands from channel bridges and dispatches them to providers |
| netipmid | openbmc/phosphor-net-ipmid | The network IPMI bridge (RMCP+ on UDP 623) |
| entity-manager | openbmc/entity-manager | Detects hardware with probes and publishes its configuration ("Exposes") on D-Bus |
| fru-device | part of entity-manager | Scans I2C buses for IPMI FRU EEPROMs, a common detection daemon |
| phosphor-user-manager | openbmc/phosphor-user-manager | Local and LDAP users, privilege roles, lockout policy; backs authentication for Redfish, IPMI, SSH and the host console |
| phosphor-certificate-manager | openbmc/phosphor-certificate-manager | HTTPS server certificates, trust stores and LDAP client certificates |
| phosphor-bmc-code-mgmt | openbmc/phosphor-bmc-code-mgmt | Firmware image staging, signature checks, activation and priority |
| phosphor-logging | openbmc/phosphor-logging | Event and error logs exposed through Redfish |
| obmc-ikvm | openbmc/obmc-ikvm | Remote KVM video |
| Dropbear | upstream | SSH on TCP 22 and the host console over SSH on TCP 2200 |
How a Redfish request flows
A Redfish GET for a temperature reading goes like this: the client opens TLS to bmcweb on TCP 443; bmcweb authenticates the user through PAM and phosphor-user-manager; it checks the route's privilege against the Redfish privilege registry ("All authorization in bmcweb is determined at routing time, and per route"); it asks the ObjectMapper which services own sensor objects, reads their properties and renders JSON. The same objects answer an ipmitool sensor request through netipmid and ipmid, which is why a bug in one daemon can surface through several front doors.
bmcweb authentication modes
The bmcweb README lists the authentication methods it supports: Basic authentication per RFC 7617, cookie based authentication for the web UI, mutual TLS with client certificates, session authentication through the web UI, and XToken authentication conformant to Redfish DSP0266. Each can be switched off at build time in meson.options, and the README says they can also be enabled or disabled at runtime "through the relevant Redfish APIs." All username and password checks go through libpam.
The build options include a block the file itself introduces with a warning: "Every option that starts with a insecure flag should not be enabled by default for any platform." Those are insecure-disable-csrf, insecure-disable-ssl, insecure-disable-auth, insecure-ignore-content-type, insecure-push-style-notification and insecure-enable-redfish-query. A production build should have every one of them disabled. Other defaults worth knowing: the Phosphor D-Bus REST API (rest) is disabled by default, KVM and virtual media WebSockets are enabled, and tls-profile defaults to modern, which applies the Mozilla "modern" TLS configuration.
IPMI inside OpenBMC
The IPMI architecture document describes IPMI as "commands and channels." Channels are bridge processes: one for the host side (KCS or BT interfaces on the LPC or eSPI bus), one for the network (RMCP+ on UDP 623), and optionally IPMB. Each bridge strips the transport framing, packages the command as a D-Bus method call to ipmid with the caller's user ID and privilege, and returns the response. Turning off the network bridge does not affect in band IPMI from the host operating system, which many tools still use.
The user management document notes a limit that shapes hardening: IPMI "cannot be used to authenticate against LDAP, since IPMI needs the password in clear text" on the BMC. Users who need IPMI over LAN must be local accounts with reversibly stored passwords. That is one more reason to disable it.
Users, groups and roles
phosphor-user-manager uses two dimensions. Groups decide which interfaces a user may use: ssh, ipmi, redfish and hostconsole. Privilege roles decide what they may do: admin (full control including users and network), operator ("view and control basic operations," such as host reboot, but not users or network) and user (read only). Redfish exposes these as the standard Administrator, Operator and ReadOnly roles. For LDAP accounts, OpenBMC maps LDAP groups to privilege roles; the mapping must exist before LDAP users can log in.
Which BMC chips and platforms does OpenBMC run on?
BMC system on chip families
The SoC support layers show which chips the project builds for:
| Chip family | Layer and include | Notes from the tree and docs |
|---|---|---|
| ASPEED AST2400 and AST2500 | meta-aspeed, ast2400.inc, ast2500.inc | The flash layout doc calls JFFS2 "the default filesystem in OpenBMC" on these chips, which have 1 or 2 GB of DDR and flash "typically in the 10s of MB." The AST2500 can boot from an alternate flash on failure |
| ASPEED AST2600 | meta-aspeed, ast2600.inc | Supports first stage loader signing with socsec against a key in OTP memory |
| ASPEED AST2700 | meta-aspeed, ast2700.inc | SOC_FAMILY = "aspeed-g7", Cortex-A35 tuning, FIT images with Arm Trusted Firmware and a TEE (UBOOT_FIT_ARM_TRUSTED_FIRMWARE = "1", UBOOT_FIT_TEE = "1"); the docs repo has an ast27x0.md design |
| Nuvoton NPCM7xx and NPCM8xx | meta-nuvoton, npcm7xx.inc, npcm8xx.inc | Evaluation boards evb-npcm750 and evb-npcm845 are in the supported list |
| HPE GXP | meta-hpe/meta-gxp, gxp.inc | Includes a fitimage-sign.inc that inherits Yocto's uboot-sign class, with signing set to "0" and a key named dev |
The README's FAQ is candid about what "supported" means. "Most of the platforms supported by OpenBMC are specialized servers operated by companies running large datacenters," some generic commercial boards are supported "to varying degrees," and even a listed board may not be a supported system, because fan control depends on the chassis and fans. The supported-machines.md list says plainly that "the specific level of functionality supported is unknown and has no level of warranty, promise of future development, or bug-fix guarantee."
How OEMs and hyperscalers use it
The supported machines list groups boards under the organisations that contributed them: more than twenty silicon makers, server and switch builders, original design manufacturers and datacenter operators, plus evaluation boards. Three usage patterns show up in the tree and docs:
- Operators who build their own BMC firmware. Large datacenter operators maintain their own layers, follow master closely and ship builds to their fleets. The Google OEM design document in the docs repo is a good example of what that enables: it adds a
google/v1service root for root of trust chips that "will never be capable of supporting standards based interface," while noting the future of its RoT devices is SPDM. - Server makers who base product firmware on OpenBMC. A vendor adds its machine layer and OEM features and ships the result. To the buyer it looks like any vendor BMC; the difference is whether the vendor shares its SBOM or source.
- Board makers and silicon vendors who keep a reference port. Evaluation boards such as
evb-ast2600andevb-npcm845let others start from working code.
DC-SCM: the BMC on a card
The Open Compute Project's Datacenter Secure Control Module specification (revision 1.0, 11 March 2021) changes where the BMC lives. It "moves common server management, security, and control features from a typical processor motherboard architecture onto a smaller common form factor module." The rest of the server becomes a Host Processor Module (HPM), described as "similar to today's motherboard with BMC and Security circuitry removed." The two connect through the Datacenter-ready Secure Control Interface (DC-SCI). The spec's SPI example includes an optional root of trust for attestation of BMC and BIOS flash.
OpenBMC already carries at least one DC-SCM machine in its supported list (mtmitchell-dcscm). The appeal for security teams is that one module design, one BMC firmware build and one root of trust can be reused across several server generations, and updated without redesigning the motherboard.
How does OpenBMC handle secure boot, signed images and dual flash?
There are three separate questions here, and they are often blurred: does the hardware verify the first code it runs, does each boot stage verify the next, and does the update service refuse unsigned images. OpenBMC has answers to all three, but most of them are opt in.
Stage 1: the chip verifies the first loader
Hardware rooted secure boot is a property of the BMC chip. On the ASPEED AST2600, the socsec-sign.bbclass in meta-aspeed explains: "ASPEED AST2600 devices can use Aspeed's utility 'socsec' to sign the SPL (pubkey written to OTP region)." The class defaults are telling:
SOCSEC_SIGN_ENABLE ?= "0"
SOCSEC_SIGN_KEY ?= ""
SOCSEC_SIGN_SOC ?= "2600"
SOCSEC_SIGN_ALGO ?= "RSA4096_SHA512"
When enabled, the build signs the U-Boot SPL with your RSA key and then runs socsec verify against the OTP image configurations, failing the build with "Verified OTP image failed" on a mismatch. The class warns that SPL signing "is only supported on AST2600 boards." Writing the public key hash into one time programmable memory is a manufacturing decision that cannot be undone, so it is planned with the board maker, not toggled in the field.
Stage 2: U-Boot verifies the kernel
From the flash layout document: U-Boot was "selected as the bootloader," and in the UBI layout "the bootcmd script loads a kernel from a FIT image." FIT images can carry signatures, and Yocto's uboot-sign class can sign them. In the OpenBMC tree you can see this pattern in the HPE GXP include, which inherits uboot-sign, sets SHA-512 for FIT hashes, and leaves UBOOT_SIGN_ENABLE = "0" with a key named dev. In other words, the plumbing exists, and turning it on with your own key is a platform decision. The main README still lists "Verified Boot" under "Features In Progress," which is an honest signal that there is no single, project wide verified boot chain that every board gets for free.
Stage 3: the update service checks signatures
Image signing for updates lives in meta-phosphor/classes/image_types_phosphor.bbclass. The relevant lines:
SIGNING_PUBLIC_KEY ?= ""
SIGNING_KEY ?= "${STAGING_DIR_NATIVE}${datadir}/OpenBMC.priv"
INSECURE_KEY = "${@'${SIGNING_KEY}' == '${STAGING_DIR_NATIVE}${datadir}/OpenBMC.priv'}"
If SIGNING_KEY is left at its default, the build pulls in phosphor-insecure-signing-key-native, whose recipe summary is "Insecure private key for testing and development" and whose install step prints "Using an insecure image signing key!" Each image part (U-Boot, kernel, read only filesystem, read write filesystem, MANIFEST, public key) is signed with openssl dgst -sha256 -sign, the signatures are concatenated into image-full, and image-full is signed too. If you set SIGNING_PUBLIC_KEY instead, the build packages your public key and expects the signing to happen elsewhere, for example in a hardware security module. Setting both is an error.
On the BMC, the code update document describes what happens next. The tarball holds five files (U-Boot, kernel, read only and read write partitions, MANIFEST), plus the public key and signatures. The MANIFEST carries purpose, version, KeyType, HashType and MachineName, and the updater uses MachineName to refuse images built for another board. The version ID is the first eight hex characters of a SHA-512 hash of the version string, which you can compute before upload:
tar xfO obmc-phosphor-image-romulus.static.mtd.tar MANIFEST \
| sed -ne '/version=/ {s/version=//;p}' | head -n1 | tr -d '\n' \
| sha512sum | cut -b 1-8
Dual images and recovery
OpenBMC supports several flash layouts:
| Layout | How it is stored | Redundancy notes from the docs |
|---|---|---|
| Static (JFFS2 on MTD) | Read only squashfs in an MTD partition plus a JFFS2 read write partition, assembled by an initramfs | The default on AST2400 and AST2500 systems; one image |
UBI on MTD (obmc-ubi-fs) | Squashfs in a static UBI volume, UBIFS for /var, overlay on /etc and /home | Targeted at systems with "enough flash storage to store at least 2 copies of the filesystem," which "can be accomplished with dual flash storage"; supports alternate flash boot on chips such as the AST2500 |
| eMMC (ext4) | Partitions on eMMC | Described as a work in progress in the flash layout doc, with a separate eMMC design document |
The update service keeps track of images with D-Bus associations. "Functional" points at the running image, "active" at every image that could boot, and each image has a priority. After an update you can see both the old and new images until you remove one, which is what makes rollback possible.
Mapping it to NIST SP 800-193
NIST SP 800-193 (May 2018) organises platform firmware resiliency around "protecting the platform against unauthorized changes, detecting unauthorized changes that occur, and recovering from attacks rapidly and securely." Here is how OpenBMC's pieces line up, and what you still have to supply:
| SP 800-193 principle | OpenBMC mechanism | What you must decide or add |
|---|---|---|
| Protection | Signed update images; MachineName check; read only root filesystem; SPL signing on AST2600 | Your own signing key in an HSM; enabling socsec and FIT signing; locking flash write protection on the board |
| Detection | Signature verification at update time; secure boot checks when enabled; root of trust attestation on DC-SCM style designs | A hardware root of trust or attestation path; a process to compare measurements against known good values |
| Recovery | Dual images on UBI and dual flash layouts; alternate boot on supported chips; factory reset | Keeping a known good image on the second flash; a tested procedure for restoring a BMC that fails to boot |
How does the OpenBMC project handle security reports and advisories?
The reporting process
The docs repository's SECURITY.md points to security/how-to-report-a-security-vulnerability.md. The process changed in recent years: the openbmc-security@lists.ozlabs.org list "is no-longer the first point-of-contact." Instead, reporters open a draft security advisory on GitHub against the source repository of the affected component, with "CVE identifier" set to "Request CVE ID later."
A report must name the affected component and repository, explain why it is a security issue, name the platform it was shown on, identify the earliest commits that brought the component in, include a way to reproduce it against a BMC, quote relevant specifications, propose a patch and give the reporter's legal name for credit. It must reproduce on a commit from master less than a week old, with one report per vulnerability and no binary attachments.
Two details stand out. The policy excludes issues "discovered with AI-assistance" that "do not present a security issue on a real system, or cannot be reproduced," sending those to normal contributions. And hardware vulnerabilities go straight to the security mailing list, where "software mitigations" may be applied "on a case-by-case basis."
Inside the project, a maintainer of the affected repository becomes the "issue lead," analyses the report, proposes a patch and, if appropriate, requests a CVE through GitHub. The project refers to the CERT Guide to Coordinated Vulnerability Disclosure. A named security response team, listed in security_response_team.md, receives and triages reports, and reporters who feel ignored can escalate to the list with a link to their draft advisory.
What published advisories look like
Advisories live on each component repository's GitHub security page, not in one central bulletin. On 23 October 2026 the bmcweb repository had two published advisories, and phosphor-net-ipmid, phosphor-host-ipmid, phosphor-user-manager and the main openbmc repository had none. Two dated examples show the pattern:
| Published | Advisory | Component | Summary from the advisory | Affected | Fixed |
|---|---|---|---|---|---|
| 19 Oct 2022 | GHSA-g3qc-375m-h66j (CVE-2022-2809, CVE-2022-3409) | bmcweb | Out of bounds heap and stack writes in the multipart parser, found by fuzzing; no authentication needed; CVSS 3.1 score 8.2 | 2.12 and earlier | 2.13 |
| 21 Apr 2026 | GHSA-p3gc-68x5-g9w3 | bmcweb | The HTTP 100-continue check did not enforce the maximum payload size, so crafted requests could crash the service hosting Redfish, KVM, serial over LAN and the web UI; no authentication needed; CVSS 3.1 score 7.5 | 2.18.0 and earlier | 3.0.0 |
The lesson is not about these two bugs in particular. It is that the web server in front of your BMC is a network facing C++ program that parses untrusted input before authentication, which is exactly where memory safety and resource limits matter. When you track an OpenBMC based fleet, track the bmcweb revision in each build, not just the overall firmware version, and watch the security tab of each component you ship.
What this means if you buy rather than build
If your servers run vendor firmware derived from OpenBMC, the upstream advisory is only the start. The fix reaches you when the vendor rebases or backports it and ships a new BMC image. The NSA and CISA guidance puts it plainly: "OS patch maintenance solutions do not deliver BMC updates." Ask your vendor which upstream revision their BMC is based on and how they map upstream advisories to their releases.
Hardening OpenBMC step by step
This walkthrough assumes you either build OpenBMC yourself or can ask your supplier for these settings, and that you manage BMCs through Redfish. Part A is build time. Part B is runtime, done with curl against Redfish, so you can script it across a fleet. The DMTF property names are standard; the paths that include bmc (such as /redfish/v1/Managers/bmc) are OpenBMC's, so follow @odata.id links rather than hard coding them on other firmware.
Part A: build time
A1. Build out what you do not need. In your distro or machine configuration, require the hardening includes that match your operating model:
# conf/local.conf or your machine/distro .conf
require conf/distro/include/phosphor-no-ipmi-rmcp.inc
require conf/distro/include/phosphor-no-root-login.inc
require conf/distro/include/phosphor-no-snmp.inc
# Only if nobody needs the browser UI (KVM and virtual media still need bmcweb)
# require conf/distro/include/phosphor-no-webui.inc
Building out network IPMI is stronger than disabling it at runtime, because the code is not on the BMC at all. If a tool you cannot replace still needs IPMI over LAN, skip that include and restrict UDP 623 at the network layer instead.
A2. Pin bmcweb options. In a bmcweb_%.bbappend in your layer, make the security relevant options explicit so an upstream default change cannot surprise you:
# meta-yourcompany/recipes-phosphor/interfaces/bmcweb_%.bbappend
EXTRA_OEMESON:append = " \
-Dinsecure-disable-csrf=disabled \
-Dinsecure-disable-ssl=disabled \
-Dinsecure-disable-auth=disabled \
-Dinsecure-ignore-content-type=disabled \
-Dinsecure-push-style-notification=disabled \
-Drest=disabled \
-Dtls-profile=modern \
"
If you use mutual TLS for automation, keep mutual-tls-auth enabled. If nobody uses HTTP Basic authentication, consider -Dbasic-auth=disabled so every client must use a session or a certificate.
A3. Sign with your own key. Generate a key pair, keep the private key off developer laptops, and point the build at it:
# One time, on the signing host (ideally backed by an HSM)
openssl genrsa -out obmc-prod.priv 4096
openssl rsa -in obmc-prod.priv -pubout -out obmc-prod.pub
# In your distro or machine configuration
SIGNING_KEY = "/secure/keys/obmc-prod.priv"
# or, to sign outside the build:
# SIGNING_PUBLIC_KEY = "/secure/keys/obmc-prod.pub"
Then confirm the insecure key is gone. The build log should not contain "Using an insecure image signing key!", and the public key packaged in the tarball should match yours:
tar xfO obmc-phosphor-image-<machine>.static.mtd.tar publickey | openssl rsa -pubin -noout -modulus | sha256sum
openssl rsa -pubin -in obmc-prod.pub -noout -modulus | sha256sum
A4. Turn on boot verification your chip supports. On AST2600 boards, plan SPL signing with SOCSEC_SIGN_ENABLE = "1" and a real SOCSEC_SIGN_KEY, and coordinate OTP programming with the board maker. Where your platform uses FIT images, enable uboot-sign with your own key instead of a development key.
A5. Keep the SBOM and check it. Archive the .spdx.json produced for every image you ship, alongside the image itself. If your Yocto base supports it, enable the sbom-cve-check fragment and review Unpatched entries before release.
Part B: runtime over Redfish
Set up once per shell. Pin the CA that signed the BMC certificate (or, on first contact with a factory BMC, the self signed certificate you fetched and verified out of band) instead of using curl's insecure mode:
export BMC=bmc01.mgmt.example.internal
export CA=/etc/pki/bmc/ca.pem # or the pinned factory cert on first run
read -s -p "BMC password: " BMCPASS; echo
B1. Confirm you are talking to the right BMC. Every write below changes a production management controller. Before each block, check the identity of the target:
curl -s --cacert "$CA" -u "admin:$BMCPASS" https://$BMC/redfish/v1/Managers/bmc \
| jq '{Id, FirmwareVersion, UUID, Model}'
curl -s --cacert "$CA" -u "admin:$BMCPASS" https://$BMC/redfish/v1/Systems/system \
| jq '{SerialNumber, HostName}'
Compare the serial number and UUID with your inventory before going further.
B2. Create a session and stop sending the password. OpenBMC's network guide notes that X-Auth tokens are required for POST, PUT, PATCH and DELETE when using the Phosphor REST paths, and sessions are the cleaner model for Redfish too:
TOKEN=$(curl -s --cacert "$CA" -D - -o /dev/null \
-H "Content-Type: application/json" \
-X POST https://$BMC/redfish/v1/SessionService/Sessions \
-d "{\"UserName\":\"admin\",\"Password\":\"$BMCPASS\"}" \
| awk -F': ' 'tolower($1)=="x-auth-token"{print $2}' | tr -d '\r')
H=(-H "X-Auth-Token: $TOKEN" -H "Content-Type: application/json")
B3. Replace default credentials and lock down accounts. OpenBMC's own examples use root with the password 0penBmc. NSA and CISA's first recommendation is "Change the default BMC credentials as soon as possible" and to create unique administrator accounts. Create named accounts, then change or disable root:
# Create a named administrator (choose a strong, unique password)
curl -s --cacert "$CA" "${H[@]}" -X POST https://$BMC/redfish/v1/AccountService/Accounts \
-d '{"UserName":"ops-admin","Password":"<new strong password>","RoleId":"Administrator","Enabled":true}'
# Read only account for monitoring
curl -s --cacert "$CA" "${H[@]}" -X POST https://$BMC/redfish/v1/AccountService/Accounts \
-d '{"UserName":"monitor","Password":"<another strong password>","RoleId":"ReadOnly","Enabled":true}'
# After confirming ops-admin works, disable the default root account
curl -s --cacert "$CA" "${H[@]}" -X PATCH https://$BMC/redfish/v1/AccountService/Accounts/root \
-d '{"Enabled":false}'
Test the new administrator in a second terminal before disabling root, so you cannot lock yourself out. If your build includes phosphor-no-root-login, root is already locked.
B4. Set lockout and session limits. The OpenBMC network guide recommends delaying failed logins and limiting orphaned sessions, because automated agents with bad credentials can cause denial of service. Redfish exposes both:
curl -s --cacert "$CA" "${H[@]}" -X PATCH https://$BMC/redfish/v1/AccountService \
-d '{"AccountLockoutThreshold":5,"AccountLockoutDuration":600,"MinPasswordLength":12}'
curl -s --cacert "$CA" "${H[@]}" -X PATCH https://$BMC/redfish/v1/SessionService \
-d '{"SessionTimeout":900}'
Pick a threshold that will not lock out your own automation. A lockout that a misconfigured script can trigger is itself an availability risk.
B5. Turn off network protocols you do not use. The OpenBMC Redfish cheat sheet shows IPMI being disabled through the NetworkProtocol resource. Do the same for SSH if your operations do not need a BMC shell; the network guide says shell access "gives the operator more privilege than is needed":
curl -s --cacert "$CA" "${H[@]}" -X PATCH https://$BMC/redfish/v1/Managers/bmc/NetworkProtocol \
-d '{"IPMI":{"ProtocolEnabled":false},"SSH":{"ProtocolEnabled":false}}'
# Keep NTP on, so logs and certificate checks have correct time
curl -s --cacert "$CA" "${H[@]}" -X PATCH https://$BMC/redfish/v1/Managers/bmc/NetworkProtocol \
-d '{"NTP":{"ProtocolEnabled":true,"NTPServers":["ntp1.mgmt.example.internal"]}}'
B6. Replace the self signed HTTPS certificate. OpenBMC ships "an auto-generated self-signed server certificate." The project's TLS configuration guide uses the CertificateService ReplaceCertificate action, which takes the private key and certificate as one PEM string. The guide requires the server certificate's common name to match the BMC's fully qualified name and keys of at least 2048 bits:
# server-key.pem and server-cert.pem issued by your internal CA for $BMC
jq -n --arg pem "$(cat server-key.pem server-cert.pem)" '{
CertificateString: $pem,
CertificateType: "PEM",
CertificateUri: {"@odata.id": "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates/1"}
}' > replace_cert.json
curl -s --cacert "$CA" "${H[@]}" -X POST \
https://$BMC/redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate \
-d @replace_cert.json
Using jq to build the JSON avoids the hand escaping of newlines the guide describes. Handle the private key file with care: it should exist only on the issuing host and the BMC.
B7. Optional: mutual TLS for automation. The same guide shows installing your CA into the BMC trust store (/redfish/v1/Managers/bmc/Truststore/Certificates) and enabling TLS client authentication through an OpenBMC OEM property on AccountService (Oem.OpenBMC.AuthMethods.TLS). Client certificates must carry clientAuth in Extended Key Usage, and by default the common name must match an existing BMC user name. That lets automation authenticate without any password on disk.
B8. Use LDAP for people, local accounts for break glass. Redfish's AccountService has an LDAP object with service addresses, bind credentials, search settings and a RemoteRoleMapping list. OpenBMC requires the group to role mapping before LDAP users can log in, and LDAP does not work for IPMI:
curl -s --cacert "$CA" "${H[@]}" -X PATCH https://$BMC/redfish/v1/AccountService -d '{
"LDAP": {
"ServiceEnabled": true,
"ServiceAddresses": ["ldaps://ldap.example.internal"],
"Authentication": {"AuthenticationType":"UsernameAndPassword",
"Username":"cn=bmc-bind,ou=svc,dc=example,dc=internal",
"Password":"<bind password>"},
"LDAPService": {"SearchSettings": {
"BaseDistinguishedNames": ["dc=example,dc=internal"],
"UsernameAttribute": "uid",
"GroupsAttribute": "memberOf"}},
"RemoteRoleMapping": [
{"RemoteGroup":"bmc-admins","LocalRole":"Administrator"},
{"RemoteGroup":"bmc-operators","LocalRole":"Operator"}]
}}'
Use ldaps://, and keep one local administrator in your vault for when the directory is unreachable.
B9. Verify everything from Redfish and from the network. Read the settings back rather than trusting the PATCH responses:
curl -s --cacert "$CA" "${H[@]}" https://$BMC/redfish/v1/Managers/bmc/NetworkProtocol \
| jq '{IPMI: .IPMI.ProtocolEnabled, SSH: .SSH.ProtocolEnabled, HTTPS: .HTTPS.ProtocolEnabled}'
curl -s --cacert "$CA" "${H[@]}" https://$BMC/redfish/v1/AccountService \
| jq '{AccountLockoutThreshold, AccountLockoutDuration, MinPasswordLength, LDAP: .LDAP.ServiceEnabled}'
curl -s --cacert "$CA" "${H[@]}" https://$BMC/redfish/v1/AccountService/Accounts \
| jq -r '.Members[]."@odata.id"'
curl -s --cacert "$CA" "${H[@]}" https://$BMC/redfish/v1/UpdateService/FirmwareInventory \
| jq -r '.Members[]."@odata.id"'
# From a management host: the certificate should chain to your CA
openssl s_client -connect $BMC:443 -servername $BMC -CAfile "$CA" </dev/null 2>/dev/null \
| grep -E 'subject=|issuer=|Verify return code'
# From a management host: UDP 623 should not answer if IPMI over LAN is off
sudo nmap -sU -p 623 $BMC
Finish by deleting your session (DELETE on the session URI returned at login) so tokens do not linger.
B10. Firmware updates with care. Before any update, repeat the identity check in B1, confirm the image's MachineName matches the target, and confirm it was signed with your key. A failed BMC flash can leave a server unmanageable until someone reaches it physically. On dual image systems, keep the previous image until the new one has run cleanly:
# WARNING: this writes firmware to the BMC. Re-run the B1 identity check first.
tar xfO image.static.mtd.tar MANIFEST | grep -E '^(MachineName|version)='
URI=$(curl -s --cacert "$CA" "${H[@]}" https://$BMC/redfish/v1/UpdateService | jq -r .MultipartHttpPushUri)
curl -s --cacert "$CA" -H "X-Auth-Token: $TOKEN" -X POST https://$BMC$URI \
-F 'UpdateParameters={"Targets":["/redfish/v1/Managers/bmc"],"@Redfish.OperationApplyTime":"OnReset"};type=application/json' \
-F "UpdateFile=@image.static.mtd.tar;type=application/octet-stream"
OnReset stages the image and applies it at the next BMC reset, so you choose the moment.
Hardening decision table
| Control | Build time option | Runtime option | Prefer |
|---|---|---|---|
| Network IPMI | phosphor-no-ipmi-rmcp | NetworkProtocol IPMI.ProtocolEnabled=false | Build time, unless a tool needs it |
| Root login | phosphor-no-root-login | Disable root account via AccountService | Both |
| Web UI | phosphor-no-webui | None; restrict by network | Build time if nobody uses it |
| BMC shell over SSH | Remove Dropbear from the image | NetworkProtocol SSH.ProtocolEnabled=false | Runtime off, with a documented break glass path |
| Basic auth | -Dbasic-auth=disabled | Redfish policy, where exposed | Sessions or mutual TLS for automation |
| Insecure web options | All insecure-* options disabled | Not available | Build time, always |
| Image signing | Your own SIGNING_KEY or SIGNING_PUBLIC_KEY | Not available | Build time, always |
| Secure boot | SOCSEC_SIGN_ENABLE, uboot-sign | Not available | Where the chip supports it |
| HTTPS certificate | None | ReplaceCertificate | Runtime, from your CA |
| Directory login | pam_ldap in image | AccountService LDAP with role mapping | Runtime, with a local break glass admin |
| Network exposure | isolate-bmc where supported | None on the BMC; OpenBMC "does not have a firewall" | Dedicated management VLAN |
How do OpenBMC, proprietary BMC firmware and DC-SCM modular BMCs compare?
The three options are not mutually exclusive. A DC-SCM card can run OpenBMC or proprietary firmware, and a vendor's proprietary firmware can itself be derived from OpenBMC. The table compares the typical case for each, focusing on what a security team can control and verify.
| Aspect | OpenBMC (self built or shared source) | Proprietary vendor BMC firmware | DC-SCM style modular BMC |
|---|---|---|---|
| Who controls update timing | You, for self built images; the supplier otherwise | The vendor's release schedule | Whoever builds the module firmware; the module can be updated or replaced without changing the motherboard |
| Ability to patch a component yourself | Yes: patch the recipe in your layer and rebuild | No; wait for a vendor release | Depends on the firmware running on the module |
| SBOM availability | Generated by the Yocto build (create-spdx) when enabled | Only if the vendor publishes one | Depends on the firmware; the spec standardises the hardware interface, not the software |
| Auditability of source | Full source, public review in Gerrit, public advisories per repository | Closed source; limited to vendor documentation and advisories | Hardware interface is an open spec; firmware may be open or closed |
| Signing keys | Yours, if you replace the development key | The vendor's | Typically the operator's or module maker's; the spec's example includes an optional root of trust for BMC and BIOS flash |
| Hardware root of trust | Depends on the BMC chip and board; opt in on many builds | Vendor specific, often on by default | Designed in as a module level option |
| Effort to operate | High: you own porting, fan tables, testing and security response | Low: the vendor owns it | Medium to high at design time; lower across generations |
| Standards exposure | Redfish via bmcweb, IPMI 2.0 with DCMI | Redfish and IPMI, with vendor OEM extensions | Same software interfaces as whichever firmware runs on it |
OpenBMC trades ownership for visibility and control; proprietary firmware trades trust in the vendor's process for convenience. DC-SCM moves the hardware boundary, which makes one well governed BMC build easier to reuse, but does not answer the software questions by itself.
Common mistakes
- Shipping images signed with the development key. If
SIGNING_KEYis unset, the build signs withOpenBMC.priv, which anyone can download. Signature checks then prove nothing. Search the build log for "Using an insecure image signing key!" and fail the pipeline if it appears. - Assuming "supported machine" means production ready. The supported machines list explicitly gives no warranty of functionality. Treat a new port as a project with its own test plan.
- Leaving IPMI over LAN on "just in case." It cannot use LDAP, it needs reversible passwords on the BMC, and it is a separate network service on UDP 623. Build it out or switch it off, then check from the network.
- Disabling root before testing the replacement account. You can lock yourself out of a BMC with one PATCH. Always verify the new administrator works in a separate session first, and keep a break glass procedure.
- Using curl's insecure mode in production scripts. OpenBMC's examples use
-kfor brevity in labs. In production, pin your CA; otherwise any device on the management network can impersonate a BMC and collect credentials. - Forgetting that OpenBMC has no firewall. The project's own network guide says so. Network segmentation, as NSA and CISA recommend, is not optional.
- Tracking the firmware version but not the components. An OpenBMC based image can carry an old bmcweb or OpenSSL even when the overall version string looks recent. Keep the SBOM for each image and check component versions against advisories.
- Enabling an
insecure-*bmcweb option for debugging and never turning it off. Pin all of them todisabledin a.bbappendso a debug build cannot drift into production.
FAQ
What is OpenBMC used for?
OpenBMC is firmware for baseboard management controllers: remote power control, sensors, event logs, remote console, virtual media and firmware updates for servers, switches and storage systems. Organisations build their own BMC firmware with it or use it as the base for vendor firmware.
Who maintains OpenBMC?
OpenBMC is a Linux Foundation project. Technical direction comes from a community elected Technical Oversight Forum, and each component repository has its own maintainers. The project was announced at the Linux Foundation on 19 March 2018 with IBM contributing its code base and support from Facebook, Google, Intel and Microsoft.
Is OpenBMC the same as Facebook's OpenBMC?
They share a name and an origin, but they are separate code bases today. Facebook published its OpenBMC in March 2015 in the facebook/openbmc repository. The Linux Foundation project in github.com/openbmc grew from IBM's contributed code base and is developed by a wider community.
Does OpenBMC support Redfish?
Yes. bmcweb implements Redfish as a translator from OpenBMC's D-Bus objects, and authorization follows the Redfish privilege registry. The main README still lists "OpenCompute Redfish Compliance" as in progress, so check the specific resources your tools need.
Does OpenBMC support secure boot?
It provides building blocks: signed update images, SPL signing on ASPEED AST2600 through socsec, and FIT image signing through Yocto's uboot-sign class. Most are off by default and depend on the chip and board. The README lists "Verified Boot" as a feature in progress.
What is the default OpenBMC password?
OpenBMC's documentation examples use root with the password 0penBmc. Change or disable that account on first boot and build with phosphor-no-root-login for production. Vendor builds may differ.
How do I disable IPMI on OpenBMC?
At build time, require phosphor-no-ipmi-rmcp.inc so network IPMI is not in the image. At runtime, send a Redfish PATCH to the manager's NetworkProtocol resource with "IPMI": {"ProtocolEnabled": false}, then confirm UDP 623 no longer answers. In band IPMI from the host operating system is separate.
Which BMC chips does OpenBMC support?
The tree has support layers for ASPEED AST2400, AST2500, AST2600 and AST2700, Nuvoton NPCM7xx and NPCM8xx, and HPE's GXP. Support for a chip does not mean support for every board that uses it.
Can I get an SBOM for an OpenBMC image?
Yes, if you build it. OpenBMC uses Yocto, whose build system generates SPDX SBOMs through the create-spdx class, writing an .spdx.json file next to the image. For vendor firmware, ask the vendor for its SBOM.
How do I report a security bug in OpenBMC?
Open a draft GitHub security advisory against the affected component's repository, with a reproduction on a recent master commit and a proposed patch. Hardware issues go to the OpenBMC security mailing list.
Where Safeguard fits
Safeguard does not scan BMC firmware images, attest boot chains or manage BMCs. It fits the software around OpenBMC that your team builds: Python Redfish tooling, custom daemons, the Node.js toolchain for webui-vue, and the container images that run your hardening scripts all pull open source dependencies that need the same patch discipline as any other repository. Safeguard can scan those repositories with safeguard scan --dir ., container images with --image, and an SBOM file you already have with --sbom, writing results as JSON under ./output, and it shows which of your projects contain a given component and version. Whether a Yocto generated SPDX document is a format your Safeguard setup reads is something to check against the CLI documentation before you plan around it.
Firmware for a BMC is built from the same kind of open source components as any other Linux image, and the Redfish tools, web UI build and management hosts around it pull their dependencies again every time they are rebuilt. The steps below apply to those open source dependencies and container images, not to the BMC image itself, which still has to come from your own OpenBMC build or your server vendor.
Fix it without waiting for upstream
Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.
1. Autonomous remediation: pull requests, not tickets
When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.
2. Gold Open Source: the safe version in seconds, free
gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.
3. Gold Registry: start from components that are already fixed
registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.
When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.
| Your situation | What to use |
|---|---|
| A fixed version exists | Autonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version |
| You need to know today whether you are affected | Gold Open Source lookup and "Am I affected?" checker, free and without login |
| You want vulnerable versions to stop shipping | The Gold scan GitHub Action in CI, plus Safeguard policies and gates |
| Upstream has no fix yet, or will not ship one | A custom Gold request; fork and patch (early access) |
| You want to start clean on new projects | Pull hardened components and images from Gold Registry |
One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.
See how Safeguard would help
The demos below show Safeguard on ordinary software projects, not on BMC firmware. The first is a real Safeguard CLI session: after install, safeguard opens the interactive terminal, you ask it to fix the lodash CVE in a repository, and it reads the finding and advisory, asks before each command, edits package.json to lodash 4.17.21, runs npm install and npm test with your approval, prints a summary and pushes nothing. It ends with /permissions, /model and /scan. Point the same flow at the repository that holds your Redfish automation or a webui-vue customisation, and the steps are the same: find the vulnerable dependency, propose the change and run your tests before anything is committed.
Click through it at your own pace, or open it full screen.
BMC networks should be isolated, and so should the hosts that manage them. The local runner demo shows how to set up the runner on your own machine, approve it with its device code, and then scan from the terminal. A runner on a build machine or jump host inside the management zone can scan the tooling that lives there without opening that network to the outside.
Click through it at your own pace, or open it full screen.
If your team already uses Claude, the third demo shows how to connect Claude to the Safeguard MCP server with OAuth and choose which tools Claude can use. An engineer can then ask about vulnerable dependencies in the projects that hold your BMC inventory and hardening scripts, using only the tools you have allowed.
Click through it at your own pace, or open it full screen.
To try it on your own repositories, download Safeguard and follow the CLI documentation.
Quick check
Your OpenBMC update images pass signature verification on every board. Why might that prove nothing?
If SIGNING_KEY was never set, the build signed them with OpenBMC.priv from the phosphor-insecure-signing-key-native recipe, a development key anyone can download. Set your own SIGNING_KEY or SIGNING_PUBLIC_KEY, and fail the build if the log says "Using an insecure image signing key!"
You disabled IPMI through Redfish NetworkProtocol. Is IPMI completely gone from the BMC?
No. Network IPMI (RMCP+ on UDP 623) is off, but the netipmid code is still in the image, and in band IPMI from the host over KCS or BT still works through ipmid. To remove network IPMI from the image entirely, build with phosphor-no-ipmi-rmcp, then confirm from the network that UDP 623 does not answer.
Sources
- OpenBMC, documentation repository README
- OpenBMC, openbmc repository README (build, CI, features, TOF)
- OpenBMC, features list
- OpenBMC, How to report a security vulnerability
- OpenBMC, Security response team
- OpenBMC, Network security considerations
- OpenBMC, How to configure the server TLS certificates for authentication
- OpenBMC, User management architecture
- OpenBMC, IPMI architecture
- OpenBMC, ObjectMapper
- OpenBMC, Code update
- OpenBMC, Flash layout and filesystem
- OpenBMC, Redfish cheat sheet
- OpenBMC, Google specific APIs design (RootOfTrust service root)
- OpenBMC, Supported machines
- OpenBMC, image_types_phosphor.bbclass (image signing)
- OpenBMC, phosphor-insecure-signing-key-native recipe
- OpenBMC, socsec-sign.bbclass (AST2600 SPL signing)
- OpenBMC, ast2700.inc machine include
- OpenBMC, GXP fitimage-sign.inc
- OpenBMC, distro feature includes (phosphor-no-ipmi-rmcp, phosphor-no-root-login and others)
- OpenBMC, bmcweb README
- OpenBMC, bmcweb meson.options
- OpenBMC, entity-manager README
- OpenBMC, bmcweb advisory GHSA-g3qc-375m-h66j (CVE-2022-2809)
- OpenBMC, bmcweb advisory GHSA-p3gc-68x5-g9w3
- OpenBMC project site
- Linux Foundation, OpenBMC Project Community Comes Together at The Linux Foundation (19 March 2018)
- Engineering at Meta, Introducing OpenBMC: an open software framework for next-generation system management (10 March 2015)
- GitHub, facebook/openbmc repository
- Yocto Project, Overview and Concepts Manual: Introducing the Yocto Project
- Yocto Project, Development Manual: Understanding and creating layers
- Yocto Project, Development Manual: Creating a Software Bill of Materials
- Yocto Project, Security Manual: Checking for vulnerabilities
- Open Compute Project, Datacenter Secure Control Module (DC-SCM) Specification revision 1.0 (11 March 2021)
- NIST, SP 800-193 Platform Firmware Resiliency Guidelines (May 2018)
- CISA, CISA and NSA Release Joint Guidance on Hardening Baseboard Management Controllers (14 June 2023)
- NSA and CISA, Cybersecurity Information Sheet: Harden Baseboard Management Controllers (June 2023, archived copy)
Last reviewed: 23 October 2026. OpenBMC moves quickly; check the linked repositories for current build options, supported machines and advisories before you plan a build.