Open-source project
systemd/particleos avatar
systemd/particleos

ParticleOS is an immutable OS you build and sign with your own keys

⸭ An image-based, secure OS, built on top of various Linux distributions

624 stars70 forksShellLGPL-2.1

At a glance

What is it?
ParticleOS is a fully customizable immutable distribution built on top of Arch, Fedora or Debian with mkosi, where the image is assembled and signed by the user rather than downloaded from a vendor. The result is a system you control end to end, and an update path that depends on systemd-sysupdate and on your own signing key.
Who is it for?
Adopt ParticleOS if you want an immutable system whose image and update chain are signed by keys you control, and you are prepared to build and maintain that chain yourself. Do not adopt it for a machine you do not own the build of, since the whole trust model depends on your key, and do not adopt it expecting a stable contract, because the README states there are no backwards compatibility guarantees at all.
Can I use it commercially?
Yes, with conditions. LGPL-2.1 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly Shell, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

You build the image and you hold the signing key

ParticleOS is described as a fully customizable immutable distribution implementing the concepts described in the Fitting Everything Together article by Lennart Poettering, and the README is direct about what makes it different.

The crucial difference compared to other immutable distributions is that users build the ParticleOS image themselves and sign it with their own keys, instead of installing vendor signed images. That gives full control over which distribution is used as the base and which packages are installed into the image, and it moves the trust anchor from the vendor to you.

The trade is equally real. A vendor signed image gives you a chain of trust that a third party vouches for. A self signed image gives you one that nobody else vouches for, which means your key management, your key backup and your update infrastructure become your responsibility. For a fleet you administer, that is often the point. For a laptop, it is a burden that a prebuilt image would not impose.

Two caveats from the README should be read first. ParticleOS is still in development, and there are no backwards compatibility guarantees at all. The primary language is Shell, the licence is LGPL-2.1, the default branch is main, there are no GitHub releases, and the last push was on 2026-10-19.

The repository root is a mkosi configuration tree. There is mkosi.conf and a mkosi.conf.d/ directory, profile directories such as mkosi.profiles/, mkosi.uki-profiles/ for unified kernel images, mkosi.repart/ for partition definitions, mkosi.sysupdate/ for the update configuration, mkosi.images/, mkosi.credentials/, mkosi.extra/ and mkosi.finalize, plus a .obs/ directory and a TODO file.

mkosi does the work, ParticleOS supplies the decisions

The ParticleOS image is built using mkosi, and the README says you need to install the current main branch of mkosi to build current ParticleOS images. That is a meaningful requirement: a released mkosi will not do, so the tool that builds your operating system has to track the tool that the operating system is built with.

The division of labour is clean. mkosi is the general purpose image builder, and ParticleOS is a set of decisions expressed in mkosi configuration files: which distribution to base on, which packages to install, how to partition the disk, how to build the unified kernel image, what to put in the update configuration, and which signing keys to use. Adding support for a distribution that mkosi already supports is, in the README's words, as simple as writing the necessary config files to install the required packages for that distribution. Currently arch, fedora and debian are supported.

The top level files make the same point. mkosi.bump, mkosi.clean, mkosi.postinst.chroot and mkosi.extra/ are the hooks mkosi calls at each stage of the build, mkosi.repart/ holds the partition definitions that describe the disk layout, and mkosi.sysupdate/ holds the configuration that systemd-sysupdate reads to know what an update looks like and how to verify it.

That is the shape of an image based system: the disk layout, the files placed into it, the update definitions and the credentials all live in version control, and the installed system is a consequence of those files rather than a set of manual choices made on the machine.

Configuring a desktop variant

Configuration starts with a local file, mkosi.local.conf, which is where you declare the variant you want. For a desktop system the README says you want the desktop profile and one of gnome, kde or sway, and the example is short:

conf
[Distribution]
Distribution=arch

[Config]
Profiles=desktop,kde

The two sections do what they say. The Distribution section names the base distribution, here arch, and the Config section lists the profiles to apply, here desktop and kde.

The profiles directory is where those names come from. Profiles are how the same base image becomes a minimal server, a GNOME desktop, a KDE desktop or a sway desktop, and how optional behaviour is switched on, such as the obs-repos profile discussed later.

The README also strongly recommends writing a hashed root password prefixed with hashed: to a file called mkosi.rootpw, so you can debug the system if something breaks. That is a small detail with a large practical meaning. A desktop image that will not boot, on a system with an encrypted root and no recovery shell, is a brick, and a hashed root password is the cheapest possible escape hatch. The hashing requirement is there so the password is not sitting in the repository in plain text.

The build itself is one command run from the ParticleOS repository, the command `mkosi -B -f`. The -B flag points mkosi at a build directory, and -f forces the build to be reconfigured rather than reusing the previous configuration.

Updates run through systemd-sysupdate on your own key

The update story is the part of an image based system that decides whether it is usable, and ParticleOS uses systemd-sysupdate for it.

To update, the README says you clone the ParticleOS repository or your fork of it, make sure mkosi.local.conf is configured to your liking, and run `mkosi -B -ff sysupdate -- update --reboot`.

That updates the system using systemd-sysupdate and then reboots. The -ff flag is the force flag applied twice, which is how mkosi is told to rebuild the image rather than reuse the previous one, and the sysupdate subcommand invokes the update logic that systemd-sysupdate drives.

The design point is that updating is not an in-place mutation of the running system. A new image is produced, the update is transferred, it is verified against the keys you configured, and the system reboots into it. That is the immutability guarantee, and it is also why the signing key is not optional.

The README is explicit that the key must be stored safely, because it is required to sign updates. Lose that key and you cannot produce an update your own machine will accept, which turns a key backup from a security nicety into an availability requirement.

This is also where the choice of running the newest systemd starts to matter, because systemd-sysupdate is the component that performs the transfer and the verification, and its behaviour evolves with systemd itself.

The obs-repos profile runs systemd straight from git

ParticleOS sometimes adopts systemd features as soon as they are merged upstream, without waiting for an official release, and the mechanism for that is a profile.

The obs-repos profile enables the systemd repositories on the Open Build Service, which host systemd packages built every day from systemd's git main branch. Enabling it means adding this to mkosi.local.conf:

conf
[Config]
Profiles=obs-repos

There is a second option, obs-repos-stable, which uses the latest stable branch of systemd instead of main, providing more stability and less risk, as the README puts it, because it is what distributions typically use.

The alternative to the OBS repositories is to build systemd from source yourself, and the README gives the full sequence. You clone systemd, then use mkosi to drive a sandboxed meson build:

sh
git clone https://github.com/systemd/systemd
cd systemd
mkosi -f sandbox -- meson setup build
mkosi -f sandbox -- meson compile -C build
mkosi -t none -f

The final step builds a ParticleOS image from the artifacts you just produced, and the README then shows how to point ParticleOS at them with a VolatilePackageDirectories entry under the Content section and an ExtraSearchPaths entry under the Build section, with the caveat that the distribution and release must be identical in the systemd checkout and the ParticleOS checkout.

That caveat is the one to watch. The two checkouts have to agree on the distribution and release, and a mismatch produces a broken image rather than a clear error.

Secure Boot with a smartcard and a YubiKey

ParticleOS images are signed for Secure Boot with the user's keys, and mkosi generates them. The command is mkosi genkey, and the README repeats the requirement that the key must be stored safely because it is required to sign updates.

A plain file key is configured in mkosi.local.conf, and the block is the whole configuration:

code
[Validation]
SecureBootKey=pkcs11:object=Private key 1;type=private
SecureBootKeySource=provider:pkcs11
SignExpectedPcrKey=pkcs11:object=Private key 1;type=private
SignExpectedPcrKeySource=provider:pkcs11
VerityKey=pkcs11:object=Private key 1;type=private
VerityKeySource=provider:pkcs11

The keys are addressed through a PKCS#11 provider, and the three keys do three different jobs. SecureBootKey signs the image so the firmware will boot it, SignExpectedPcrKey signs the expected PCR values, and VerityKey signs the dm-verity root hash so the filesystem contents can be verified. Signing the image alone is not enough for a verified boot chain.

The key can live on a smartcard, and the README shows the YubiKey route with ykman generating an RSA2048 key and a certificate in PIV slot 9c, then pkcs11-tool listing the objects to confirm the token is present. The listing it expects includes the certificate label, the subject DN with CN=mkosi, the serial and the ID, and the pkcs11 URI that identifies the token.

The configuration for that case is longer, because the slot and token have to be named explicitly rather than left as the default object, so the key identifiers become pkcs11:token=mkosi;id=%%02;type=private, with separate entries for the certificates.

Prebuilt images exist, but with a different trust model

If building every image is too much, ParticleOS images are built on the Open Build Service and can be downloaded and installed. Currently x86-64 GNOME flavours of Fedora and Debian are provided, and they are found in the images directory of the download repository. The sources are in the obs branch of the repository and the build configuration is in the system:systemd project on OBS.

Those images contain systemd built from the latest git main rather than what the distributions provide, and there is a second set built from the latest stable branch in the system:systemd:stable project, with the same ParticleOS configuration and only the systemd packages differing. The README describes the stable set as the safer and more stable option.

The trust model of the prebuilt images is different from the self built ones, and the difference is the point. Any private key material used to sign the images is handled automatically and securely by OBS and is not available to the project maintainers. The OBS signing certificate and the MSFT third party 2011 and 2023 CAs are set up to be self-enrolled for UEFI Secure Boot.

So there are two coherent options rather than one compromise. Build and sign the image yourself, and the trust anchor is your key, with all the backup and availability obligations that implies. Or take the OBS build, and the trust anchor is Open Build Service, with signed images and a maintained systemd, and the guarantee that the maintainers cannot read your key material because they never have it.

The licence is LGPL-2.1, which is the usual choice for a systemd-adjacent project, and the repository carries a LICENSE file at the root.

Editorial conclusion

Adopt ParticleOS if you want an immutable system whose image and update chain are signed by keys you control, and you are prepared to build and maintain that chain yourself. Do not adopt it for a machine you do not own the build of, since the whole trust model depends on your key, and do not adopt it expecting a stable contract, because the README states there are no backwards compatibility guarantees at all. Before you build, install the current main branch of mkosi as the README requires, and decide whether you want systemd from the OBS repositories or from a local source build.

Frequently asked questions

What is ParticleOS?

ParticleOS is a fully customizable immutable distribution implementing the concepts described in the Fitting Everything Together article. It is built on top of existing Linux distributions, currently arch, fedora and debian, using mkosi, and the README states that it is still in development with no backwards compatibility guarantees at all.

How do I build a ParticleOS image?

You install the current main branch of mkosi, configure your variant in mkosi.local.conf, for example choosing a distribution and the desktop and kde profiles, optionally write a hashed root password to mkosi.rootpw, and then run `mkosi -B -f` from the ParticleOS repository.

How do I update a ParticleOS system?

You clone the ParticleOS repository or your fork, make sure mkosi.local.conf is configured as you like it, and run `mkosi -B -ff sysupdate -- update --reboot`, which updates the system using systemd-sysupdate and reboots. The signing key you generated is required to sign those updates, so it has to be stored safely.

Can ParticleOS use a systemd version that is not released yet?

Yes. The obs-repos profile enables the systemd repositories on the Open Build Service, which build packages daily from systemd's git main branch, and the obs-repos-stable profile uses the latest stable branch instead. You can also build systemd from source with mkosi and point ParticleOS at the resulting artifacts.

Official sources

  1. Issues
  2. License: LGPL-2.1
  3. README
  4. systemd/particleos on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/systemd-particleos.svg)](https://hysenlabs.com/projects/systemd-particleos)

Was this useful?