Skip to content

tailor.yaml reference

tailor.yaml is the workspace manifest: it configures toolchains, runtime defaults, and image discovery. tailor finds it by walking up from the current directory.

schemaVersion: 1

toolchains:
  default: ic
  entries:
    - name: ic
      container: mcr.microsoft.com/azurelinux/imagecustomizer
      # version: "1.3.0"
      # tag: "1.3.0"
      # pull: missing

defaults:
  outputs:
    - format: cosi
Field Type Required Notes
schemaVersion integer yes Current value: 1. tailor rejects a version newer than it supports.
previewFeatures list of strings no Opt in to features not yet part of the stable 1.0 contract. Currently: signing. Using a gated feature (e.g. signing:) without listing it here is a hard error.
toolchains.default string yes Default toolchain name for images that omit toolchain:.
toolchains.entries list of {name, container, version?, tag?, pull?} yes Named toolchain definitions. Each name must be unique. tag defaults to version, else latest; pull defaults to missing.
toolsDirSources list of {name, container, tag?, pull?} no Named tools-dir sources. Each name must be unique. tag defaults to latest; pull defaults to missing. Images opt in with toolsDir.source.
runtime.engine enum no Container engine: docker (default), podman, or auto. See Select a container engine.
runtime.host string no Explicit engine endpoint (unix://…, a bare socket path, or tcp://…), overriding the engine default and DOCKER_HOST / CONTAINER_HOST.
runtime.privileged bool no Default true; IC requires privileged container execution.
runtime.mounts.hostRoot path no Default /host; namespace prefix for translated host paths. tailor no longer binds host / there.
runtime.mounts.dev bool no Default true; bind /dev:/dev.
runtime.mounts.extraPaths list of extra mount objects no Additional paths exposed under hostRoot. access defaults to ro; use rw only for explicit writable carve-outs. Relative paths resolve against the workspace root.
runtime.buildDirBase path no Host filesystem base for per-cell IC build dirs (<buildDirBase>/<slug>). Omit to use the default under the output dir (<output>/.tailor/build). Must not be /, a system directory, or $HOME.
runtime.logLevel enum no IC log level: panic, fatal, error, warn, info, debug, trace.
runtime.logDir path no Directory for on-disk IC log files (one per cell). Off by default (logs stream to the console). Overridden, highest precedence first, by the --log-dir flag then the TAILOR_LOG_DIR environment variable.
runtime.imageCacheDir path no Cache for registry base images. Default: <workspace>/.tailor/cache. Required by IC for oci/azureLinux bases — tailor supplies the default so they build out of the box.
runtime.janitorImage {container, tag?} no Minimal image used for sudo-free ownership cleanup. Default: mcr.microsoft.com/azurelinux/base/core:3.0.
signing.default string no Signing profile used when an image says signing: true. See Sign an image.
signing.profiles map of {backend, …} no Named signing profiles. backend is local-test-ca (optional publishCaCert: where to write the enrollable CA certificate), keypair (needs key+cert), or azure-key-vault (needs vault+certificate).
defaults.outputs output list no Inherited by images without outputs.
defaults.outputArtifacts enum no Default output.artifacts staging policy for images that don't set their own: managed (default — relocate the extracted artifacts to the output dir and keep them), scratch (treat as signing scratch: extract, then reclaim), or strip (drop the output.artifacts block so IC never extracts). A per-image outputArtifacts overrides this.
export.outputDir path cond Committed directory for tailor export output (one <slug>.yaml per cell), relative to the workspace root. Required to run tailor export argument-free. See Export.
export.scope enum no What tailor export emits. Defaults to configsOnly (the only value today); omit it.
export.images list of strings no Restrict tailor export to a subset of images. Default: all images.
baseImages list of {name, path, arch?, source?} no Base-image catalogue: named slots an image references with base: { ref: <name> }. Each name must be unique. See base-image catalogue.
images object no Omit to auto-discover every immediate */image.yaml. Optional keys: members, exclude, inline, and autoDiscover (extra workspace-relative directories to scan; see Image discovery).

Runtime mounts expose only the workspace (read-only), tailor-owned writable carve-outs, and declared out-of-workspace inputs. The old whole-host -v /:/host bind is never emitted.

Pull policy

Toolchains and tools-dir sources support pull: always | missing | never:

  • always resolves the image from its registry and pulls before use.
  • missing (default) uses a local image when present, otherwise resolves and pulls from the registry. If tailor.lock already pins a digest for the named source, the locked digest wins.
  • never requires a locked digest or a local image and never contacts the registry.

Local images that expose a RepoDigest are lockable and run as container@sha256:…. Local-only images without a RepoDigest run by their image Id and are intentionally omitted from tailor.lock.

A local toolchain image serves the architecture it was built for. tailor reads that architecture during resolution and fails fast, before any container run, when it cannot provide a selected cell's arch (rather than letting Docker attempt a slow, doomed cross-arch pull):

error: toolchain `local-ic` local image is `amd64` but cell `gizmo_arm64_cosi` targets `arm64`;
       no local image for that arch and pull policy won't fetch it

pull: never with no local image and no locked digest fails the same way — never silently reaching a registry. See Use a locally-built Image Customizer image.

A toolchain entry with every optional key set:

toolchains:
  default: ic
  entries:
    - name: ic
      container: mcr.microsoft.com/azurelinux/imagecustomizer
      version: "1.3.0"     # optional semver metadata; used as the tag when `tag` is unset
      tag: "1.3.0"         # the registry tag actually pulled (defaults to `version`, else `latest`)
      pull: missing        # always | missing (default) | never
runtime:
  buildDirBase: /mnt/tailor-build
  mounts:
    hostRoot: /host
    dev: true
    extraPaths:
      - path: /opt/shared-scripts
      - path: /data/scratch
        access: rw

Tools-dir sources

toolsDirSources: is a list of named container root filesystems that tailor can export, cache, bind, and pass to IC as --tools-dir. This is useful for sealed/minimal images whose target root does not contain a package manager. The cache is tailor-owned under runtime.imageCacheDir/tools-dirs/<digest> and is bound read-only by default. tailor never passes --tools-dir /.

toolsDirSources:
  - name: base
    container: mcr.microsoft.com/azurelinux/base/core
    tag: "3.0"
    pull: missing
  - name: fedora
    container: quay.io/fedora/fedora
    tag: "42"
Field Type Required Notes
name string yes Unique source name used by image toolsDir.source.
container string yes Container image whose flattened root filesystem becomes the tools dir.
tag string no Registry tag. Defaults to latest when container has no tag or digest.
pull always|missing|never no Pull policy. Defaults to missing; see Pull policy.

Run tailor lock to pin named tools-dir source digests in tailor.lock. Local-only tools-dir images without a registry digest are usable by local image Id, but are not lockable.

Base-image catalogue

baseImages: is a list of named slots, each a local base-image file plus an optional remote source tailor bases download pulls it from. An image references a slot by name with base: { ref: <name> }, so the path lives once here instead of being repeated (with brittle ../ counts) in every image.

baseImages:
  - name: baremetal
    path: bases/baremetal.vhdx      # build input + download output (workspace-root-relative)
    arch: amd64                     # amd64 | arm64; reconciles with the cell arch
    source:                         # optional: how `tailor bases download` fills the slot
      azureLinux:
        version: "3.0"
        variant: baremetal
  - name: core_arm64
    path: bases/core_arm64.vhdx
    arch: arm64
    source:
      oci:
        uri: registry.example/core:3.0
  - name: qemu
    path: bases/qemu.vhdx           # no source: filled out-of-band (e.g. a CI feed)
Field Type Required Notes
name string yes Unique slot name used by base: { ref: <name> }.
path path yes The slot file: build input and download output. Workspace-root-relative.
arch amd64|arm64 no The base's architecture; reconciles with the referencing cell's arch. Absent ⇒ the cell decides.
source {oci} or {azureLinux} no A remote source download pulls for linux/<arch>. Absent ⇒ pre-placed; download skips it.

Fill slots with tailor bases download and assert presence with tailor bases verify. See Use a base-image catalogue and Base images.

Export

The export: block configures tailor export, which renders each cell's merged Image Customizer config to a committed directory so a pipeline can build the images without tailor.

export:
  outputDir: rendered      # committed output dir, relative to the workspace root
  # scope: configsOnly     # optional; defaults to configsOnly (the only scope today)
  # images: [gadget]       # optional; default = all images
Field Type Req Meaning
outputDir path yes Committed directory receiving one <slug>.yaml per cell. Relative to the workspace root.
scope enum no What to emit; defaults to configsOnly. An enum so future scopes can be added without a breaking change — omit it today.
images list of strings no Restrict to a subset of images. Default: all.

With this block present, tailor export and tailor export --check run with no arguments — the --check form is a drift gate for a pre-commit hook or CI (it fails on any changed, missing, or stale file). See Export configs for a pipeline.

Image discovery

With no images: key, tailor discovers every */image.yaml at depth 1 from the workspace root.

To discover images under additional directories, list them in autoDiscover (each is workspace-root-relative; .. and absolute paths are rejected). For example, to also pick up subproject/*/image.yaml:

images:
  autoDiscover:
    - subproject/

autoDiscover extends discovery — the default depth-1 scan of the root still applies (and it also extends an explicit members: list).

To curate explicitly:

images:
  members:
    - "*"
    - tools
  exclude:
    - scratch
  inline:
    - name: tiny
      base:
        path: ./bases/tiny.img
      outputs:
        - format: cosi
      config:
        os:
          hostname: tiny

Relative paths in tailor.yaml resolve against the workspace root. Relative paths in an image.yaml resolve against that image directory.