Skip to content

Recipe

A recipe is firn's TOML installation input. This page summarizes the current fields; the full recipe specification is the exact contract for types, validation patterns and compatibility.

Unknown fields and enum values are errors. firn never guesses the image family or silently converts a recipe. See headless installation for a complete starting example.

Version and sections

Set version = 2 at top level. The recipe contains [image], [target], [security] and [system]. Add [system.user] only when creating a user.

Image

Field Meaning
family Required; exactly "bootc".
ref Required OCI image reference. Registry installs pin a reported valid source digest during preflight.
target_ref Optional post-install update reference; defaults to ref.
cosign_pub_key Optional public-key path enabling independent cosign verification of a registry source digest.

Unsigned digest pinning does not verify the publisher. If an unsigned source reports no valid digest, the tag is kept. See the trust model.

Target

Field Meaning
disk Required whole-disk /dev/… path. A by-id path must resolve to a whole disk. Confirmation matches the path as written.
filesystem Required: "btrfs", "xfs" or "ext4".
btrfs_subvolumes Optional bool, default false; with btrfs only, creates @, @home, @snapshots.
bootloader Optional: "systemd" (default) or "grub2".

ZFS is unsupported. See disk layouts.

Security

Field Meaning
encryption Required: "none", "luks-passphrase", "tpm2-luks" or "tpm2-luks-passphrase".
passphrase / passphrase_file Exactly 1 when the mode includes passphrase; neither for other modes. Prefer a private file.
mok Required when Secure Boot is active: "enroll" or "skip". Must not be set when Secure Boot is inactive.
mok_password_file Required for mok = "enroll"; contains the one-time MokManager password. Must not be set with mok = "skip" or when Secure Boot is inactive.

TPM modes require a detected TPM. Enrollment needs a person to complete MokManager at first boot. See encryption and Secure Boot.

System and user

[system] field Meaning
hostname Required valid host name, up to 253 characters.
locale Optional ll_CC[.ENC], for example en_US.UTF-8.
timezone Optional IANA zone name, for example America/Chicago; must exist in zoneinfo.
keyboard Optional XKB LAYOUT[:VARIANT[:MODEL]].
flatpaks Optional array of Flatpak application IDs.
core_flatpaks Optional bool, default false; install the selected image's published core set.
root_ssh_authorized_key / root_ssh_authorized_key_file Optional inline or file-based root SSH public-key records; at most 1 variant.

Empty or omitted locale, timezone and keyboard keep the image defaults. Flatpaks explains core-list validation and offline behavior.

Omit [system.user] to create no user. When present:

Field Meaning
name Required POSIX username, up to 32 characters.
fullname Optional full name; Unicode is allowed, but colon and line breaks are rejected.
password_file / password_hash Exactly 1: a private plaintext-password file or a precomputed crypt hash.
groups Optional supplementary groups. Names are validated; absent image groups are skipped with group_missing.
ssh_authorized_key / ssh_authorized_key_file Optional inline or file-based user SSH public-key records; at most 1 variant.

SSH values accept newline-separated OpenSSH public-key records. Supported types include ssh-ed25519, ssh-rsa, ecdsa-sha2-* and OpenSSH sk-* types. Blank lines, private keys and authorized_keys options are not accepted; a final newline is allowed.

File and secret rules

Every *_file value must name an existing regular file at validation time. Secret-valued files (passphrase_file, mok_password_file, password_file) must not be world-readable; use 0600. Inline and file variants of the same value are mutually exclusive.

The wizards write session-owned secret files instead of inline passwords. Precomputed user password hashes and installer-environment SSH key file paths are headless-only representations. Protect recipes and referenced files; do not paste their secrets into logs or issue reports.

Bootc-v1 compatibility

Bootc version = 1 remains accepted with a deprecation warning until 2026-12-30T00:00:00Z. On and after that instant, the validator rejects it with expired-version. No environment variable moves the compiled-in cutoff. Older releases that lack the cutoff change can behave differently.

To migrate, confirm family = "bootc", validate every bootc field and referenced file on the intended new medium, then change only version = 1 to version = 2. Old firn releases cannot consume v2 recipes. There is no automatic upgrade or downgrade.

A/B-v1 is rejected with family-scope, not converted. In v2, family = "ab" and A/B-only fields such as image.product or target.var_filesystem are errors. See the compatibility contract for the exact diagnostics.