Skip to content

Latest commit

 

History

History
1155 lines (961 loc) · 58 KB

platform.md

File metadata and controls

1155 lines (961 loc) · 58 KB

Platform Interface Specification

This document specifies the interface between a lifecycle and a platform.

A platform orchestrates a lifecycle to make buildpack functionality available to end-users such as application developers.

Examples of a platform might include:

  1. A local CLI tool that uses buildpacks to create OCI images
  2. A plugin for a continuous integration service that uses buildpacks to create OCI images
  3. A cloud application platform that uses buildpacks to build source code before deployment

Table of Contents

Platform API Version

This document specifies Platform API version 0.9.

Platform API versions:

  • MUST be in form <major>.<minor> or <major>, where <major> is equivalent to <major>.0
  • When <major> is greater than 0 increments to <minor> SHALL exclusively indicate additive changes

Terminology

CNB Terminology

A buildpack refers to software compliant with the Buildpack Interface Specification.

A stack is a contract, implemented by a build image and run image, that guarantees properties of the build environment and app image.

A stack ID uniquely identifies a particular stack.

A build image is an OCI image that provides the base of the build environment.

A run image is an OCI image that provides the base from which app images are built.

A mixin is a named set of additions to a stack that can be used to make additive changes to the contract.

The build environment refers to the containerized environment in which the lifecycle executes buildpacks.

An app image refers to an OCI image generated by the lifecycle by extending the run image with any or all of the following: app layers, launch layers, launcher layers, image configuration.

A launch layer refers to a layer in the app image created from a <layers>/<layer> directory as specified in the Buildpack Interface Specification.

An app layer refers to a layer in the app image created from the <app> directory as specified in the Buildpack Interface Specification.

A run image layer refers to a layer in the app image originating from the run image.

A launcher layer refers to a layer in the app OCI image containing the launcher itself and/or launcher configuration.

The launcher refers to a lifecycle executable packaged in the app image for the purpose of executing processes at runtime.

Additional Terminology

An image reference refers to either a tag reference or digest reference.

A tag reference refers to an identifier of form <registry>/<repo>:<tag> which locates an image manifest in an OCI Distribution Specification compliant registry.

A digest reference refers to a content addressable identifier of form <registry>/<repo>@<digest> which locates an image manifest in an OCI Distribution Specification compliant registry.

The following is a non-exhaustive list of terms defined in the OCI Image Format Specification used throughout this document:

Stacks

A typical stack might specify:

  • The OS distro in the build environment.
  • OS packages installed in the build environment.
  • Trusted CA certificates in the build environment.
  • The OS distro or distroless OS in the launch environment.
  • OS packages installed in the launch environment.
  • Trusted CA certificates in the launch environment.
  • The default user and the build and launch environments.

Stack authors SHOULD define the contract such that any stack images CVEs can be addressed with security patches without violating the compatibility guarantees.

Stack ID

Stack authors MUST choose a globally unique ID, for example: "io.buildpacks.mystack".

The stack ID:

  • MUST NOT be identical to any other stack ID when using a case-insensitive comparison.
  • MUST only contain numbers, letters, and the characters ., /, and -.
  • SHOULD use reverse domain name notation to avoid name collisions.

Build Image

The platform MUST ensure that:

  • The image config's User field is set to a non-root user with a writable home directory.
  • The image config's Env field has the environment variable CNB_STACK_ID set to the stack ID.
  • The image config's Env field has the environment variable CNB_USER_ID set to the user UID/SID of the user specified in the User field.
  • The image config's Env field has the environment variable CNB_GROUP_ID set to the primary group GID/SID of the user specified in the User field.
  • The image config's Env field has the environment variable PATH set to a valid set of paths or explicitly set to empty (PATH=).
  • The image config's Label field has the label io.buildpacks.stack.id set to the stack ID.
  • The image config's Label field has the label io.buildpacks.stack.mixins set to a JSON array containing mixin names for each mixin applied to the image.

The platform SHOULD ensure that:

  • The image config's Label field has the label io.buildpacks.stack.maintainer set to the name of the stack maintainer.
  • The image config's Label field has the label io.buildpacks.stack.homepage set to the homepage of the stack.
  • The image config's Label field has the label io.buildpacks.stack.distro.name set to the name of the stack's OS distro.
  • The image config's Label field has the label io.buildpacks.stack.distro.version set to the version of the stack's OS distro.
  • The image config's Label field has the label io.buildpacks.stack.released set to the release date of the stack.
  • The image config's Label field has the label io.buildpacks.stack.description set to the description of the stack.
  • The image config's Label field has the label io.buildpacks.stack.metadata set to additional metadata related to the stack.

Run Image

The platform MUST ensure that:

  • The image config's Label field has the label io.buildpacks.stack.id set to the stack ID.
  • The image config's Label field has the label io.buildpacks.stack.mixins set to a JSON array containing mixin names for each mixin applied to the image.
  • The image config's Env field has the environment variable PATH set to a valid set of paths or explicitly set to empty (PATH=).

The platform SHOULD ensure that:

  • The image config's User field is set to a user with a DIFFERENT user UID/SID as the build image.
  • The image config's Label field has the label io.buildpacks.stack.maintainer set to the name of the stack maintainer.
  • The image config's Label field has the label io.buildpacks.stack.homepage set to the homepage of the stack.
  • The image config's Label field has the label io.buildpacks.stack.distro.name set to the name of the stack's OS distro.
  • The image config's Label field has the label io.buildpacks.stack.distro.version set to the version of the stack's OS distro.
  • The image config's Label field has the label io.buildpacks.stack.released set to the release date of the stack.
  • The image config's Label field has the label io.buildpacks.stack.description set to the description of the stack.
  • The image config's Label field has the label io.buildpacks.stack.metadata set to additional metadata related to the stack.

Mixins

A mixin name MUST only be defined by the author of its corresponding stack. A mixin name MUST always be used to specify the same set of changes. A mixin name MUST only contain a : character as part of an optional stage specifier.

A mixin prefixed with the build: stage specifier only affects the build image and does not need to be specified on the run image. A mixin prefixed with the run: stage specifier only affects the run image and does not need to be specified on the build image. A mixin WITHOUT a build: or run: prefix affects both the build and the run images.

A platform MAY support any number of mixins for a given stack in order to support application code or buildpacks that require those mixins.

Changes introduced by mixins SHOULD be restricted to the addition of operating system software packages that are regularly patched with strictly backwards-compatible security fixes. However, mixins MAY consist of any changes that follow the Compatibility Guarantees.

Compatibility Guarantees

Stack image authors SHOULD ensure that build image versions maintain ABI-compatibility with previous versions, although violating this requirement will not change the behavior of previously built images containing app and launch layers.

Stack image authors MUST ensure that new run image versions maintain ABI-compatibility with previous versions. Stack image authors MUST ensure that app and launch layers do not change behavior when the run image layers are upgraded to newer versions, unless those behavior changes are intended to fix security vulnerabilities.

Mixin authors MUST ensure that mixins do not affect the ABI-compatibility of any object code compiled to run on the base stack images without mixins.

During build, platforms MUST use the same set of mixins for the run image as were used in the build image (excluding mixins that have a stage specifier).

Lifecycle Interface

Platform API Compatibility

The platform SHOULD set CNB_PLATFORM_API=<platform API version> in the lifecycle's execution environment

If CNB_PLATFORM_API is set in the lifecycle's execution environment, the lifecycle:

  • MUST either conform to the matching version of this specification or
  • MUST fail if it does not support <platform API version>

Operations

Build

A single app image build* consists of the following phases:

  1. Analysis
  2. Detection
  3. Cache Restoration
  4. Build*
  5. Export

A platform MUST execute these phases either by invoking the following phase-specific lifecycle binaries in order:

  1. /cnb/lifecycle/analyzer
  2. /cnb/lifecycle/detector
  3. /cnb/lifecycle/restorer
  4. /cnb/lifecycle/builder
  5. /cnb/lifecycle/exporter

or by executing /cnb/lifecycle/creator.

* build is an overloaded term that refers to both a single phase and the operation comprised of the above phases. The meaning of any particular instance of the word build must be assessed in context

Rebase

When an updated run image with the same stack ID is available, an updated app image SHOULD be generated from the existing app image config by replacing the run image layers in the existing app image with the layers from the new run image. This is referred to as rebasing the app, launch, and launcher layers onto the new run image layers. When layers are rebased, any app image metadata referencing to the original run image MUST be updated to reference to the new run image. This entire operation is referred to as rebasing the app image.

Rebasing allows for fast runtime OS-level dependency updates for app images without requiring a rebuild. A rebase requires minimal data transfer when the app and run images are colocated on a Docker registry that supports Cross Repository Blob Mounts.

To rebase an app image a platform MUST execute the /cnb/lifecycle/rebaser or perform an equivalent operation.

Launch

/cnb/lifecycle/launcher is responsible for launching user and buildpack provided processes in the correct execution environment. /cnb/lifecycle/launcher, or a symlink to it (see exporter outputs), SHALL be the ENTRYPOINT for all app images.

Usage

All lifecycle phases:

  • MUST read CNB_PLATFORM_API from the execution environment and evaluate compatibility before attempting to parse other inputs (see Platform API Compatibility)
  • MUST give command line inputs precedence over other inputs

analyzer

Usage:

/cnb/lifecycle/analyzer \
  [-analyzed <analyzed>] \
  [-cache-image <cache-image>] \
  [-daemon] \ # sets <daemon>
  [-gid <gid>] \
  [-launch-cache <launch-cache>] \
  [-layers <layers>] \
  [-log-level <log-level>] \
  [-previous-image <previous-image> ] \
  [-run-image <run-image> ] \
  [-skip-layers <skip-layers> ] \
  [-stack <stack> ] \
  [-tag <tag>...] \
  [-uid <uid>] \
  <image>
Inputs
Input Environment Variable Default Value Description
<analyzed> CNB_ANALYZED_PATH <layers>/analyzed.toml Path to output analysis metadata (see analyzed.toml
<cache-image> CNB_CACHE_IMAGE Reference to a cache image in an OCI image registry
<daemon> CNB_USE_DAEMON false Analyze image from docker daemon
<gid> CNB_GROUP_ID Primary GID of the build image User
<layers> CNB_LAYERS_DIR /layers Path to layers directory
<image> Tag reference to which the app image will be written
<launch-cache> CNB_LAUNCH_CACHE_DIR Path to a cache directory containing launch layers
<log-level> CNB_LOG_LEVEL info Log Level
<previous-image> CNB_PREVIOUS_IMAGE <image> Image reference to be analyzed (usually the result of the previous build)
<run-image> CNB_RUN_IMAGE resolved from <stack> Run image reference
<skip-layers> CNB_SKIP_LAYERS false Do not restore SBOM layer from previous image
<stack> CNB_STACK_PATH /cnb/stack.toml Path to stack file (see stack.toml)
<tag>... Additional tag to apply to exported image
<uid> CNB_USER_ID UID of the build image User

-<image> MUST be a valid image reference

  • If the platform provides one or more <tag> inputs, each <tag> MUST be a valid image reference.
  • If <daemon> is false and the platform provides one or more <tag> inputs, each <tag> MUST refer to the same registry as <image>.
  • If <daemon> is false, <previous-image>, if provided, MUST be a valid image reference.
  • If <daemon> is true, <previous-image>, if provided, MUST be either a valid image reference or an imageID.
  • If <skip-layers> is true the lifecycle MUST NOT restore the SBOM layer (if any) from the previous image.
  • If <run-image> is not provided by the platform the lifecycle MUST resolve the run image from the contents of stack or fail if stack does not contain a valid run image.
  • The lifecycle MUST accept valid references to non-existent <previous-image>, <cache-image>, and <image> without error.
  • The lifecycle MUST ensure registry write access to <image>, <cache-image> and any provided <tag>s.
  • The lifecycle MUST ensure registry read access to <previous-image>, <cache-image>, and <run-image>.
Outputs
Output Description
[exit status] (see Exit Code table below for values)
/dev/stdout Logs (info)
/dev/stderr Logs (warnings, errors)
<analyzed> Analysis metadata (see analyzed.toml
Exit Code Result
0 Success
11 Platform API incompatibility error
12 Buildpack API incompatibility error
1-10, 13-99 Generic lifecycle errors
30-39 Analysis-specific lifecycle errors
  • The lifecycle MUST write analysis metadata to <analyzed>, where:
    • image MUST describe the <previous-image>, if accessible
    • run-image MUST describe the <run-image>

detector

The platform MUST execute detector in the build environment

Usage:

/cnb/lifecycle/detector \
  [-app <app>] \
  [-buildpacks <buildpacks>] \
  [-group <group>] \
  [-layers <layers>] \
  [-log-level <log-level>] \
  [-order <order>] \
  [-plan <plan>] \
  [-platform <platform>]
Inputs
Input Environment Variable Default Value Description
<app> CNB_APP_DIR /workspace Path to application directory
<buildpacks> CNB_BUILDPACKS_DIR /cnb/buildpacks Path to buildpacks directory (see Buildpacks Directory Layout)
<group> CNB_GROUP_PATH <layers>/group.toml Path to output group definition
<layers> CNB_LAYERS_DIR /layers Path to layers directory
<log-level> CNB_LOG_LEVEL info Log Level
<order> CNB_ORDER_PATH <layers>/order.toml if present, or /cnb/order.toml Path resolution for order definition (see order.toml)
<plan> CNB_PLAN_PATH <layers>/plan.toml Path to output resolved build plan
<platform> CNB_PLATFORM_DIR /platform Path to platform directory
Outputs
Output Description
[exit status] (see Exit Code table below for values)
/dev/stdout Logs (info)
/dev/stderr Logs (warnings, errors)
<group> Detected buildpack group (see group.toml)
<plan> Resolved Build Plan (see plan.toml)
Exit Code Result
0 Success
11 Platform API incompatibility error
12 Buildpack API incompatibility error
1-10, 13-19 Generic lifecycle errors
20 All buildpacks groups have failed to detect w/o error
21 All buildpack groups have failed to detect and at least one buildpack has errored
22-29 Detection-specific lifecycle errors

The lifecycle:

  • SHALL detect a single group from <order> and write it to <group> using the detection process outlined in the Buildpack Interface Specification
  • SHALL write the resolved build plan from the detected group to <plan>

restorer

Usage:

/cnb/lifecycle/restorer \
  [-analyzed <analyzed>] \
  [-cache-dir <cache-dir>] \
  [-cache-image <cache-image>] \
  [-gid <gid>] \
  [-group <group>] \
  [-layers <layers>] \
  [-log-level <log-level>] \
  [-skip-layers <skip-layers>] \
  [-uid <uid>]
Inputs
Input Environment Variable Default Value Description
<analyzed> CNB_ANALYZED_PATH <layers>/analyzed.toml Path to output analysis metadata (see analyzed.toml
<cache-dir> CNB_CACHE_DIR Path to a cache directory
<cache-image> CNB_CACHE_IMAGE Reference to a cache image in an OCI image registry
<gid> CNB_GROUP_ID Primary GID of the build image User
<group> CNB_GROUP_PATH <layers>/group.toml Path to group definition (see group.toml)
<layers> CNB_LAYERS_DIR /layers Path to layers directory
<log-level> CNB_LOG_LEVEL info Log Level
<uid> CNB_USER_ID UID of the build image User
<skip-layers> CNB_SKIP_LAYERS false Do not perform layer restoration
Outputs
Output Description
[exit status] (see Exit Code table below for values)
/dev/stdout Logs (info)
/dev/stderr Logs (warnings, errors)
<layers>/<buidpack-id>/store.toml Persistent metadata (see data format in Buildpack Interface Specification)
<layers>/<buidpack-id>/<layer>.toml Files containing the layer content metadata of each analyzed layer (see data format in Buildpack Interface Specification)
<layers>/<buidpack-id>/<layer>.sbom.<ext> Files containing the Software Bill of Materials for each analyzed layer (see Buildpack Interface Specification)
<layers>/<buidpack-id>/<layer>/*. Restored layer contents
Exit Code Result
0 Success
11 Platform API incompatibility error
12 Buildpack API incompatibility error
1-10, 13-99 Generic lifecycle errors
40-49 Restoration-specific lifecycle errors
  • For each buildpack in <group>, if persistent metadata for that buildpack exists in the analysis metadata, lifecycle MUST write a toml representation of the persistent metadata to <layers>/<buildpack-id>/store.toml
  • If <skip-layers> is true the lifecycle MUST NOT perform layer restoration.
  • Else the lifecycle MUST perform layer restoration for any app image layers or cached layers created by any buildpack present in the provided <group>.
Layer Restoration

lifeycle MUST use the provided cache-dir or cache-image to retrieve cache contents. The rules for restoration MUST be followed when determining how and when to store cache layers.

builder

The platform MUST execute builder in the build environment

Usage:

/cnb/lifecycle/builder \
  [-app <app>] \
  [-buildpacks <buildpacks>] \
  [-group <group>] \
  [-layers <layers>] \
  [-log-level <log-level>] \
  [-plan <plan>] \
  [-platform <platform>]
Inputs
Input Env Default Value Description
<app> CNB_APP_DIR /workspace Path to application directory
<buildpacks> CNB_BUILDPACKS_DIR /cnb/buildpacks Path to buildpacks directory (see Buildpacks Directory Layout)
<group> CNB_GROUP_PATH <layers>/group.toml Path to group definition (see group.toml)
<layers> CNB_LAYERS_DIR /layers Path to layers directory
<log-level> CNB_LOG_LEVEL info Log Level
<plan> CNB_PLAN_PATH <layers>/plan.toml Path to resolved build plan (see plan.toml)
<platform> CNB_PLATFORM_DIR /platform Path to platform directory
Outputs
Output Description
[exit status] (see Exit Code table below for values)
/dev/stdout Logs (info)
/dev/stderr Logs (warnings, errors)
<layers>/<buildpack ID>/<layer> Layer contents (see Buildpack Interface Specfication
<layers>/<buildpack ID>/<layer>.toml Layer metadata (see Buildpack Interface Specfication
<layers>/config/metadata.toml Build metadata (see metadata.toml)
Exit Code Result
0 Success
11 Platform API incompatibility error
12 Buildpack API incompatibility error
1-10, 13-19 Generic lifecycle errors
51 Buildpack build error
50, 52-59 Build-specific lifecycle errors
  • The lifecycle SHALL execute all buildpacks in the order defined in <group> according to the process outlined in the Buildpack Interface Specification.
  • The lifecycle SHALL add all invoked buildpacks to<layers>/config/metadata.toml.
  • The lifecycle SHALL aggregate all processes and slices returned by buildpacks in <layers>/config/metadata.toml.
  • The lifecycle SHALL record the buildpack-provided default process type in <layers>/config/metadata.toml.
    • The lifecycle SHALL treat web processes defined by buildpacks implementing Buildpack API < 0.6 as default = true.

exporter

Usage:

/cnb/lifecycle/exporter \
  [-analyzed <analyzed>] \
  [-app <app>] \
  [-cache-dir <cache-dir>] \
  [-cache-image <cache-image>] \
  [-daemon] \ # sets <daemon>
  [-gid <gid>] \
  [-group <group>] \
  [-launch-cache <launch-cache> ] \
  [-launcher <launcher> ] \
  [-layers <layers>] \
  [-log-level <log-level>] \
  [-process-type <process-type> ] \
  [-project-metadata <project-metadata> ] \
  [-report <report> ] \
  [-stack <stack>] \
  [-uid <uid> ] \
  <image> [<image>...]
Inputs
Input Environment Variable Default Value Description
<analyzed> CNB_ANALYZED_PATH <layers>/analyzed.toml Path to analysis metadata (see analyzed.toml
<app> CNB_APP_DIR /workspace Path to application directory
<cache-dir> CNB_CACHE_DIR Path to a cache directory
<cache-image> CNB_CACHE_IMAGE Reference to a cache image in an OCI image registry
<daemon> CNB_USE_DAEMON false Export image to docker daemon
<gid> CNB_GROUP_ID Primary GID of the build image User
<group> CNB_GROUP_PATH <layers>/group.toml Path to group file (see group.toml)
<image> Tag reference to which the app image will be written
<launch-cache> CNB_LAUNCH_CACHE_DIR Path to a cache directory containing launch layers
<launcher> /cnb/lifecycle/launcher Path to the launcher executable
<layers> CNB_LAYERS_DIR /layers Path to layer directory
<log-level> CNB_LOG_LEVEL info Log Level
<process-type> CNB_PROCESS_TYPE Default process type to set in the exported image
<project-metadata> CNB_PROJECT_METADATA_PATH <layers>/project-metadata.toml Path to a project metadata file (see project-metadata.toml
<report> CNB_REPORT_PATH <layers>/report.toml Path to report (see report.toml
<stack> CNB_STACK_PATH /cnb/stack.toml Path to stack file (see stack.toml
<uid> CNB_USER_ID UID of the build image User
<layers>/config/metadata.toml Build metadata (see metadata.toml
SOURCE_DATE_EPOCH Timestamp for created time in app image config
  • At least one <image> must be provided
  • Each <image> MUST be a valid tag reference
  • If <daemon> is false and more than one <image> is provided they MUST refer to the same registry
  • The <run-image> will be read from analyzed.toml
Outputs
Output Description
[exit status] Success (0), or error (1+)
/dev/stdout Logs (info)
/dev/stderr Logs (warnings, errors)
<image> Exported app image (see Buildpack Interface Specfication
Exit Code Result
0 Success
11 Platform API incompatibility error
12 Buildpack API incompatibility error
1-10, 13-19 Generic lifecycle errors
60-69 Export-specific lifecycle errors
  • The lifecycle SHALL write the same app image to each <image> tag

  • The app image:

    • MUST be an extension of the run-image in analyzed.toml
      • All run-image layers SHALL be preserved
      • All run-image config values SHALL be preserved unless this conflicts with another requirement
    • MUST contain all buildpack-provided launch layers as determined by the Buildpack Interface Specfication
    • MUST contain a layer containing all buildpack-provided Software Bill of Materials (SBOM) files for launch as determined by the Buildpack Interface Specfication if they are present
      • <layers>/sbom/launch/<buildpack-id>/sbom.<ext> MUST contain the buildpack-provided launch SBOM
      • <layers>/sbom/launch/<buildpack-id>/<layer-id>/sbom.<ext> MUST contain the buildpack-provided layer SBOM if <layer-id> is a launch layer
      • <layers>/sbom/launch/sbom.legacy.json MAY contain the legacy non-standard Bill of Materials for launch (where supported)
    • MUST contain one or more app layers as determined by the Buildpack Interface Specfication
    • MUST contain one or more launcher layers that include:
      • A file with the contents of the <launcher> file at path /cnb/lifecycle/launcher
      • One symlink per buildpack-provided process type with name /cnb/process/<type> and target /cnb/lifecycle/launcher
    • MUST contain a layer that includes <layers>/config/metadata.toml
    • If <process-type> matches a buildpack-provided process:
      • MUST have ENTRYPOINT=/cnb/process/<process-type>
    • Else if <process-type> is provided and does not match a buildpack-provided process:
      • MUST fail
    • Else if there is a buildpack-provided default process type in <layers>/config/metadata.toml:
      • MUST have ENTRYPOINT=/cnb/process/<buildpack-default-process-type>
    • Else:
      • MUST have ENTRYPOINT set to /cnb/lifecycle/launcher
    • MUST contain the following Env entries
      • CNB_LAYERS_DIR=<layers>
      • CNB_APP_DIR=<app>
      • PATH=/cnb/process:$PATH where $PATH is the value of $PATH on the run-image.
    • MUST have the working directory set to the value of <app>.
    • MUST contain the following labels
      • io.buildpacks.lifecycle.metadata: see lifecycle metadata label
      • io.buildpacks.project.metadata: the value of which SHALL be the json representation <project-metadata>
      • io.buildpacks.build.metadata: see build metadata
  • To ensure build reproducibility, the lifecycle:

    • SHOULD set the modification time of all files in newly created layers to a constant value
    • SHOULD set the created time in image config to SOURCE_DATE_EPOCH, or to a constant value if not defined
  • The lifecycle SHALL write a report to <report> describing the exported app image

  • The <layers> directory:

    • MUST include all buildpack-provided Software Bill of Materials (SBOM) files for build as determined by the Buildpack Interface Specfication if they are present
      • <layers>/sbom/build/<buildpack-id>/sbom.<ext> MUST contain the buildpack-provided build SBOM
      • <layers>/sbom/build/<buildpack-id>/<layer-id>/sbom.<ext> MUST contain the buildpack-provided layer SBOM if <layer-id> is not a launch layer.
      • <layers>/sbom/build/sbom.legacy.json MAY contain the legacy non-standard Bill of Materials for build (where supported)
  • If a cache is provided the lifecycle:

    • SHALL write the contents of all cached layers and any provided layer-associated SBOM files to the cache
    • SHALL record the diffID and layer content metadata of all cached layers in the cache

creator

The platform MUST execute creator in the build environment

Usage:

/cnb/lifecycle/creator \
  [-app <app>] \
  [-buildpacks <buildpacks>] \
  [-cache-dir <cache-dir>] \
  [-cache-image <cache-image>] \
  [-daemon] \ # sets <daemon>
  [-gid <gid>] \
  [-launch-cache <launch-cache> ] \
  [-launcher <launcher> ] \
  [-layers <layers>] \
  [-log-level <log-level>] \
  [-order <order>] \
  [-platform <platform>] \
  [-previous-image <previous-image> ] \
  [-process-type <process-type> ] \
  [-project-metadata <project-metadata> ] \
  [-report <report> ] \
  [-run-image <run-image>] \
  [-skip-restore <skip-restore>] \
  [-stack <stack>] \
  [-tag <tag>...] \
  [-uid <uid> ] \
   <image>
Inputs

Running creator SHALL be equivalent to running detector, analyzer, restorer, builder and exporter in order with identical inputs where they are accepted, with the following exceptions.

Input Environment Variable Default Value Description
<previous-image> CNB_PREVIOUS_IMAGE <image> Image reference to be analyzed (usually the result of the previous build)
<skip-restore> CNB_SKIP_RESTORE false Prevent buildpacks from reusing layers from previous builds, by skipping the restoration of any data to each buildpack's layers directory, with the exception of store.toml.
<tag>... Additional tag to apply to exported image
  • If <skip-restore> is true the creator SHALL skip sbom layer restoration and skip the entire Restore phase.
  • If the platform provides one or more <tag> inputs they SHALL be treated as additional <image> inputs to the exporter
Outputs

Outputs produced by creator are identical to those produced by exporter, with the following additional expanded set of error codes.

Exit Code Result
0 Success
11 Platform API incompatibility error
12 Buildpack API incompatibility error
1-10, 13-19 Generic lifecycle errors
20-29 Detection-specific lifecycle errors
30-39 Analysis-specific lifecycle errors
40-49 Restoration-specific lifecycle errors
50-59 Build-specific lifecycle errors
60-69 Export-specific lifecycle errors

rebaser

Usage:

/cnb/lifecycle/rebaser \
  [-daemon] \ # sets <daemon>
  [-gid <gid>] \
  [-log-level <log-level>] \
  [-report <report> ] \
  [-run-image <run-image> | -image <run-image> ] \ # -image is Deprecated
  [-uid <uid>] \
  <image> [<image>...]
Inputs
Input Environment Variable Default Value Description
<daemon> CNB_USE_DAEMON false Export image to docker daemon
<gid> CNB_GROUP_ID Primary GID of the build image User
<image> App image to rebase
<log-level> CNB_LOG_LEVEL info Log Level
<report> CNB_REPORT_PATH <layers>/report.toml Path to report (see report.toml
<run-image> CNB_RUN_IMAGE derived from <image> Run image reference
<uid> CNB_USER_ID UID of the build image User
  • At least one <image> must be provided
  • Each <image> MUST be a valid tag reference
  • If <daemon> is false and more than one <image> is provided they MUST refer to the same registry
  • If <run-image> is not provided by the platform the value will be resolved from the contents of the stack key in the io.buildpacks.lifecycle.metdata label on <image>.
Outputs
Output Description
[exit status] (see Exit Code table below for values)
/dev/stdout Logs (info)
/dev/stderr Logs (warnings, errors)
<image> Rebased app image (see Buildpack Interface Specfication
Exit Code Result
0 Success
11 Platform API incompatibility error
12 Buildpack API incompatibility error
1-10, 13-19 Generic lifecycle errors
70-79 Rebase-specific lifecycle errors
  • The lifecycle SHALL write the same app image to each <image> tag

  • The rebased app image SHALL be identical to <image>, with the following modifications:

    • Run image layers SHALL be defined as Layers in <image> up to and including the layer with diff ID matching the value of run-image.top-layer from the io.buildpacks.lifecycle.metadata label
    • Run image layers SHALL be replaced with the layers from the new <run-image>
    • The value of io.buildpacks.lifecycle.metadata SHALL be modified as follows
      • run-image.reference SHALL uniquely identify <run-image>
      • run-image.top-layer SHALL be set to the uncompressed digest of the top layer in <run-image>
    • The value of io.buildpacks.stack.* labels SHALL be modified to that of the new run-image
  • To ensure build reproducibility, the lifecycle:

    • SHOULD set the created time in image config to a constant
  • The lifecycle SHALL write a report to <report> describing the rebased app image

launcher

Usage:

/cnb/process/<process-type> [<arg>...]
# OR
/cnb/lifecycle/launcher [--] [<cmd> <arg>...]
Inputs
Input Environment Variable Default Value Description
<app> CNB_APP_DIR /workspace Path to application directory
<layers> CNB_LAYERS_DIR /layers Path to layer directory
<process-type> type of process to launch
<direct> Process execution strategy
<cmd> Command to execute
<args> Arguments to command
<layers>/config/metadata.toml Build metadata (see metadata.toml
<layers>/<buildpack-id>/<layer>/ Launch Layers

A command (<cmd>), arguments to that command (<args>), a working directory (<working-dir>), and an execution strategy (<direct>) comprise a process definition. Processes MAY be buildpack-defined or user-defined.

The launcher:

  • MUST derive the values of <cmd>, <args>, <working-dir>, and <direct> as follows:
  • If the final path element in $0, matches the type of any buildpack-provided process type
    • <process-type> SHALL be the final path element in $0
    • The lifecycle:
      • MUST select the process with type equal to <process-type> from <layers>/config/metadata.toml
      • MUST set <working-dir> to the value defined for the process in <layers>/config/metadata.toml, or to <app> if not defined
      • MUST append any user-provided <args> to process arguments
  • Else
    • If $1 is --
      • <direct> SHALL be true
      • <cmd> SHALL be $2
      • <args> SHALL be ${@3:}
      • <working-dir> SHALL be <app>
    • Else
      • <direct> SHALL be false
      • <cmd> SHALL be $1
      • <args> SHALL be ${@2:}
      • <working-dir SHALL be <app>
Outputs

If the launcher errors before executing the process it will have one of the following error codes:

Exit Code Result
11 Platform API incompatibility error
12 Buildpack API incompatibility error
80-89 Launch-specific lifecycle errors

Otherwise, the exit code shall be the exit code of the launched process.

The launcher:

Run Image Resolution

Given stack metadata containing run-image.image and a set of run-image.mirrors. The <run-image> for a given <image> shall be resolved as follows:

  • If any of run-image.image or run-image.mirrors has a registry matching that of <image>, this value will become the <run-image>
  • If none of run-image.image or run-image.mirrors has a registry matching that of <image>, <run-image.image> will become the <run-image>

Registry Authentication

The platform MAY set CNB_REGISTRY_AUTH in the lifecycle execution environment, where value of CNB_REGISTRY_AUTH MUST be valid JSON object and MAY contain any number of <regsitry> to <auth-header> mappings. If CNB_REGISTRY_AUTH is set and <registry> matches the registry of an image reference, the lifecycle SHOULD set the value of the Authorization HTTP header to <auth-header> when attempting to read or write the image located at the given reference.

If CNB_REGISTRY_AUTH is unset and a docker config.json file is present, the lifecycle SHOULD use the contents of this file to authenticate with any matching registry. The lifecycle SHOULD adhere to established docker conventions when checking for the existence of or interpreting the contents of a config.json file.

The lifecycle MAY provide other mechanisms by which a platform can supply registry credentials.

The lifecycle MUST attempt to authenticate anonymously if no matching credentials are found.

Buildpacks

Buildpacks Directory Layout

The buildpacks directory MUST contain unarchived buildpacks such that:

  • Each top-level directory is a buildpack ID.
  • Each second-level directory is a buildpack version.

Security Considerations

The platform SHOULD run each phase of the lifecycle in an isolated container to prevent untrusted app and buildpack code from accessing storage credentials needed during the export and analysis phases. A more thorough explanation is provided in the Buildpack Interface Specification.

Additional Guidance

Environment

Buildpack Environment

Stack-Provided Variables

The following variables SHOULD be set in the lifecycle execution environment and SHALL be directly inherited by the buildpack without modification:

Env Variable Description
CNB_STACK_ID Chosen stack ID
HOME Current user's home directory

The following variables SHOULD be set in the lifecycle execution environment and MAY be modified by prior buildpacks before they are provided to a given buildpack:

Env Variable Layer Path Contents
PATH /bin binaries
LD_LIBRARY_PATH /lib shared libraries
LIBRARY_PATH /lib static libraries
CPATH /include header files
PKG_CONFIG_PATH /pkgconfig pc files

The platform SHOULD NOT assume any other stack-provided environment variables are inherited by the buildpack.

User-Provided Variables

User-provided environment variables MUST be supplied by the platform as files in the <platform>/env/ directory. Each file SHALL define a single environment variable, where the file name defines the key and the file contents define the value.

User-provided environment variables MAY be modified by prior buildpacks before they are provided to a given buildpack.

The platform SHOULD NOT set user-provided environment variables directly in the lifecycle execution environment.

Launch Environment

User-provided modifications to the process execution environment SHOULD be set directly in the lifecycle execution environment.

The process SHALL inherit both stack-provided and user-provided variables from the lifecycle execution environment with the following exceptions:

  • CNB_APP_DIR, CNB_LAYERS_DIR and CNB_PROCESS_TYPE SHALL NOT be set in the process execution environment.
  • /cnb/process SHALL be removed from the beginning of PATH.
  • The lifecycle SHALL apply buildpack-provided modifications to the environment as outlined in the Buildpack Interface Specification.

Caching

If caching is enabled the platform is responsible for providing the lifecycle with access to the correct cache. Whenever possible, the platform SHOULD provide the same cache to each rebuild of a given app image. Cache locality and availability MAY vary between platforms.

Build Reproducibility

When given identical inputs all build and rebase operations:

  • SHOULD produce app images with identical imageIDs
  • If exporting directly to a registry
    • SHOULD produce app images with identical manifest digests
  • MAY output other non-reproducible artifacts

To achieve reproducibility the lifecycle SHOULD set the following to a constant, rather than an accurate value:

  • file modification times in generated layers
  • image creation time

Because compressions algorithms and manifest whitespace affect the image digest, an app image exported to the docker daemon and subsequently pushed to a registry MAY have a different digest than an app image exported directly to a registry by the lifecycle, even when all other inputs are held constant.

If buildpacks do not generate layer contents or layer metadata reproducibly, builds MAY NOT be reproducibile even when identical source code and buildpacks are provided to the lifecycle.

All app image labels SHOULD contain only reproducible values.

For more information on build reproducibility see https://reproducible-builds.org/

Data Format

Files

analyzed.toml (TOML)

[image]
  reference = "<image reference>"

[metadata]
# layer metadata

[run-image]
  reference = "<image reference>"

Where:

  • previous-image.reference MUST be either a digest reference to an image in a docker registry or the ID of an image in a docker daemon
  • run-image.reference MUST be either a digest reference to an image in a docker registry or the ID of an image in a docker daemon
  • previous-image.metadata MUST be the TOML representation of the layer metadata label

group.toml (TOML)

[[group]]
id = "<buildpack ID>"
version = "<buildpack version>"
api = "<buildpack API version>"
homepage = "<buildpack homepage>"

Where:

  • id, version, and api MUST be present for each buildpack object in a group.

metadata.toml (TOML)

buildpack-default-process-type = "<process type>"

[[buildpacks]]
id = "<buildpack ID>"
version = "<buildpack version>"
api = "<buildpack API version>"
optional = false

[[processes]]
type = "<process type>"
command = "<command>"
args = ["<arguments>"]
direct = false
working-dir = "<working directory>"

[[slices]]
paths = ["<app sub-path glob>"]

Where:

  • id, version, and api MUST be present for each buildpack
  • processes contains the complete set of processes contributed by all buildpacks
  • slices contains the complete set of slices defined by all buildpacks

order.toml (TOML)

[[order]]
[[order.group]]
id = "<buildpack ID>"
version = "<buildpack version>"
optional = false

Where:

  • Both id and version MUST be present for each buildpack object in a group.
  • The value of optional MUST default to false if not specified.

plan.toml (TOML)

[[entries]]

  [[entries.providers]]
    id = "<buildpack ID>"
    version = "buildpack Version"

  [[entries.requires]]
    name = "<dependency name>"
    [entries.requires.metadata]
      # arbitrary data describing the required dependency

Where:

  • entries MAY be empty
  • Each entry:
    • MUST contain at least one buildpack in providers
    • MUST contain at least one dependency requirement in requires
    • MUST exclusively contain dependency requirements with the same <dependency name>

project-metadata.toml (TOML)

[source]
type = "<source type>"

[source.version]
# arbitrary data

[source.metadata]
# arbitrary data

Where:

  • All values are optional
  • type, if present, SHOULD contain the type of location where the provided app source is stored (e.g git, s3)
  • version, if present, SHOULD contain data uniquely identifying the particular version of the provided source
  • metadata MAY contain additional arbitrary data about the provided source

report.toml (TOML)

[image]
tags = ["<tag reference>"]
digest = "<image digest>"
image-id = "<imageID>"
manifest-size = "<manifest size in bytes>"

Where:

  • tags MUST contain all tag references to the exported app image
  • If the app image was exported to an OCI registry
    • digest MUST contain the image digest
    • manifest-size MUST contain the manifest size in bytes
  • If the app image was exported to a docker daemon
    • imageID MUST contain the imageID

stack.toml (TOML)

[run-image]
 image = "<image>"
 mirrors = ["<mirror>", "<mirror>"]

Where:

  • run-image.image MAY be a reference to a run image in a docker registry
  • run-image.mirrors MUST NOT be present if run-image.image is not present
  • run-image.mirrors MAY contain one or more tag references to run images in docker registries
  • All run-image.mirrors:
    • SHOULD reference an image with ID identical to that of run-image.image
  • run-image.image and run-image.mirrors.[] SHOULD each refer to a unique registry

Labels

io.buildpacks.build.metadata (JSON)

{
  "processes": [
    {
      "type": "<process-type>",
      "command": "<command>",
      "args": [
        "<args>"
      ],
      "direct": false,
      "working-dir": "<working-dir>",
    }
  ],
  "buildpacks": [
    {
      "id": "<buildpack ID>",
      "version": "<buildpack version>",
      "homepage": "<buildpack homepage>"
    }
  ],
 "launcher": {
    "version": "<launcher-version>",
    "source": {
      "git": {
        "repository": "<launcher-source-repository>",
        "commit": "<launcher-source-commit>"
      }
    }
  }
}

Where:

  • processes MUST contain all buildpack contributed processes
  • buildpacks MUST contain the detected group
  • launcher.version SHOULD contain the version of the launcher binary included in the app
  • launcher.source.git.repository SHOULD contain the git repository containing the launcher source code
  • launcher.source.git.commit SHOULD contain the git commit from which the given launcher was built

io.buildpacks.lifecycle.metadata (JSON)

{
  "app": [
    {"sha": "<slice-layer-diffID>"}
  ],
  "sbom": {
    "sha": "<BOM-layer-diffID>"
  },
  "config": {
    "sha": "<config-layer-diffID>"
  },
  "launcher": {
    "sha": "<launcher-layer-diffID>"
  },
  "buildpacks": [
    {
      "key": "<buildpack-id>",
      "version": "<buildpack-version>",
      "layers": {
        "<layer-name>": {
          "sha": "<layer-diffID>",
          "data": {},
          "build": false,
          "launch": false,
          "cache": false
        }
      }
    }
  ],
  "runImage": {
    "topLayer": "<run-image-top-layer-diffID>",
    "reference": "<run-image-reference>"
  },
  "stack": {
    "runImage": {
      "image": "cnbs/sample-stack-run:bionic"
    }
  }
}

Where:

  • app MUST contain one entry per app slice layer where
    • sha MUST contain the digest of the uncompressed layer
  • sbom.sha MUST contain the digest of the uncompressed layer containing buildpack-provided Software Bill of Materials
  • config.sha MUST contain the digest of the uncompressed layer containing launcher config
  • launcher.sha MUST contain the digest of the uncompressed layer containing the launcher binary
  • buildpacks MUST contain one entry per buildpack that participated in the build where
    • key is required and MUST contain the buildpack ID
    • version is required and MUST contain the buidpack Version
    • layers is required and MUST contain one entry per launch layer contributed by the given buildpack.
    • For each entry in layers:
      • The key MUST be the name of the layer
      • The value MUST contain JSON representation of the layer.toml with an additional sha key, containing the digest of the uncompressed layer
      • The value MUST contain an additional sha key, containing the digest of the uncompressed layer
  • run-image.topLayer must contain the uncompressed digest of the top layer of the run-image
  • run-image.reference MUST uniquely identify the run image. It MAY contain one of the following
    • An image ID (the digest of the uncompressed config blob)
    • A digest reference to a manifest stored in an OCI image registry
  • stack MUST contain the json representation of stack.toml

io.buildpacks.project.metadata (JSON)

{
  "source": {
    "type": "<type>",
    "version": {
     // arbitrary version data
    },
    "metadata": {
    // arbitrary data
    }
  }
}

This label MUST contain the JSON representation of project-metadata.toml