Skip to Content
ReferenceRecipe Schema

Recipe Schema

OpenFactory recipes use snake_case JSON. The canonical format has a small top-level envelope, an os object for operating-system configuration, and a scenarios array for post-build verification.

Validation proves that recognized fields have acceptable shapes. It does not prove that every package exists, every requested behavior was represented, or the image and tests will succeed. Unknown fields may be ignored for backward compatibility, so always inspect the normalized recipe returned by the product.

Canonical Envelope

{ "name": "debian-web-check", "display_name": "Debian Web Check", "description": "Small Debian image with explicit smoke tests.", "base_image": "debian-trixie", "use_case": "Server evaluation", "hardware": {}, "os": {}, "scenarios": [], "publish_to": ["local"] }

Do not use camelCase fields such as baseImage or startupScripts. The compatibility validator accepts some older flat recipes, but normalized output nests OS fields under os. New integrations should send the canonical format.

Top-Level Fields

FieldTypeRequired/defaultMeaning
namestringRequired; 3–100 charactersStable internal recipe name
display_namestring or nullOptional; 1–100 charactersHuman-facing name
descriptionstring""Intended outcome and boundary
base_imagestringdebian-trixieDistribution/build target; use the current console list
taskstring or nullOptionalOperational goal
executorstring or nullOptionalTechnology expected to perform the task
use_casestringGeneralPrimary use case
hardwareobjectDefaults shown belowDeployment requirements
osobjectEmpty/default objectOS packages, users, services, security, desktop, installer, and scripts
scenariosarray[]Test topologies and objectives
publish_tostring array["local"]Requested output destinations
deliveryobject{}Additional declared delivery configuration
communitybooleanfalseRequest community-marketplace visibility; publication policy still applies

Advanced target-specific fields exist for source-ISO remastering, Proxmox guest payloads, policy provenance, and delivery integrations. Use the editor or API contract for the deployed release instead of copying an old example.

Hardware

{ "hardware": { "platform": "pc", "architecture": "x86_64", "gpu": null, "min_cpu_cores": 2, "min_memory_gb": 4, "min_storage_gb": 16, "nic_count": 1 } }

platform is pc, phone, or raspberry_pi; supported device values are target-specific. architecture is x86_64 or aarch64. GPU values name a supported vendor or vendor combination. These are declared requirements, not proof that a resulting image was tested on matching physical hardware.

OS Object

Common os fields are:

FieldTypePurpose
featuresstring arrayRegistered feature modules
packagesstring arrayNative packages to request
excluded_packagesstring arrayPackages that must remain absent after feature expansion
custom_packagesarraySource repositories to package through the supported build path
package_overridesarrayExplicit add, remove, or replace operations
extra_reposstring arrayAdditional repositories; trust and key handling still require review
servicesarrayNamed service enablement and configuration
usersarrayImage-local accounts and groups
securityobjectDeclared hardening, encryption, audit, SELinux, and fail2ban choices
networkingobjectInterface and network intent
desktop_settingsobjectDesktop appearance and behavior
brandingobjectDistribution identity and assets
runtimeobjectInit/service/package-manager identity
bootobjectKernel arguments and GRUB choices
installerobjectInstall-to-disk configuration
persistenceobjectLive persistence and zone policy
integrityobjectRequested dm-verity, Secure Boot, and IMA/EVM settings
file_attachmentsarrayPreviously uploaded files identified by file_id
startup_scriptsarrayBounded systemd one-shot scripts
time_zonestring or nullImage time-zone setting

The presence of an integrity or security field is configuration intent. It is not evidence that the mechanism was produced, enforced at runtime, or qualified for a compliance regime. Require matching build and test evidence.

Users

{ "os": { "users": [ { "username": "deploy", "full_name": "Deployment Operator", "groups": ["sudo"], "shell": "/bin/bash" } ] } }

User and group names are limited to safe Linux account characters and length. Leaving password unset creates a password-locked account for key-only or deployment-time credential workflows. Avoid plaintext credentials in saved recipes.

Services

{ "os": { "services": [ { "name": "ssh", "enabled": true, "config": { "port": 22, "disable_password_auth": true } } ] } }

config is service-specific. A syntactically valid key can still be ignored by a generator that does not implement it. Verify the normalized recipe, generated configuration, and guest behavior.

Security and Installer

{ "os": { "security": { "hardening_level": "standard", "disk_encryption": false, "audit_logging": true, "selinux": false, "fail2ban": true }, "installer": { "enabled": false, "type": "calamares", "desktop_launcher": true, "bootloader": "grub", "delivery": [], "user_setup": "build_time" } } }

Installer types are target-dependent (calamares, anaconda, or elster-mobile). Enabling an installer must be followed by a disposable-disk install test; an icon in a live desktop is not proof that installation works.

Startup Scripts

{ "os": { "startup_scripts": [ { "name": "write-build-marker", "description": "Create a local marker after networking is available.", "command": "install -m 0644 /dev/null /var/lib/example-ready", "packages": [], "run_as": "root", "after": "network.target" } ] } }

At most 32 startup scripts are accepted. Commands must be nonempty and cannot contain NUL bytes. Treat them as root-capable shell code unless run_as says otherwise; review idempotency, quoting, network failure, and secret exposure.

Scenarios and Assertions

{ "scenarios": [ { "id": "primary-smoke", "name": "Primary image smoke test", "enabled": true, "tests": ["boot", "login", "packages"], "custom_tests": [ { "description": "Confirm SSH is enabled on the configured port.", "assertions": [ { "type": "service_enabled", "description": "The SSH service starts at boot.", "params": {"service": "ssh"} }, { "type": "port_listening", "description": "The guest listens on TCP port 22.", "params": {"port": 22} } ] } ] } ] }

A scenario can also define a topology with VMs and networks, benchmark-format tests, and CIS settings. An omitted topology defaults to the normal single-VM path. Assertions need a human-readable description and type-specific params. Unknown assertion types may survive schema parsing, so confirm the runner supports them before treating them as evidence.

Complete Minimal Example

{ "name": "debian-web-check", "display_name": "Debian Web Check", "description": "Debian image with SSH, curl, and explicit smoke tests.", "base_image": "debian-trixie", "use_case": "Server evaluation", "hardware": { "platform": "pc", "architecture": "x86_64", "min_cpu_cores": 2, "min_memory_gb": 4, "min_storage_gb": 16, "nic_count": 1 }, "os": { "features": ["ssh"], "packages": ["curl"], "users": [ { "username": "deploy", "groups": ["sudo"], "shell": "/bin/bash" } ], "services": [ { "name": "ssh", "enabled": true, "config": {"port": 22, "disable_password_auth": true} } ], "security": { "hardening_level": "standard", "audit_logging": true }, "installer": {"enabled": false} }, "scenarios": [ { "id": "primary-smoke", "name": "Primary image smoke test", "enabled": true, "tests": ["boot", "login", "packages"] } ], "publish_to": ["local"] }

Validation Workflow

  1. Validate the JSON through the current recipe editor, API, or MCP validate_recipe tool.
  2. Compare the returned normalized recipe with the original request.
  3. Treat dropped unknown fields as a defect in the recipe, not as successful configuration.
  4. Build only after explicit requirements are represented.
  5. Inspect generated evidence and run assertions against the resulting guest.

See Your First Build for failure and download recovery guidance.