Skip to main content
CleanStart

Knowledge Hub

YAML Image Configuration

Related Fundamentals: To understand the OCI specification underlying this configuration, see Docker and OCI Specification and Container Image Layers Deep Dive.

Declaring Container Images with YAML Configuration

Traditional container image definitions use imperative Dockerfiles that describe the build process as a sequence of commands. CleanStart takes a fundamentally different approach: you declare what you want in your image using YAML configuration, and the build system figures out how to create it. This declarative approach offers numerous advantages that transform how teams manage container images.

When you define images declaratively, several key benefits emerge. First, image definitions become version-controlled alongside your application code, enabling you to track when and why image configurations change. Second, image changes go through code review like any other change, providing a security gate where team members can assess whether new dependencies introduce acceptable risk. Third, builds become reproducible—the same configuration always produces the same image, eliminating the "it works on my machine but not in production" problem. Fourth, policy validation ensures that images comply with organizational rules—for example, blocking images that use vulnerable dependencies or non-approved licenses. Finally, multi-variant generation means that a single YAML configuration automatically produces both AMD64 and ARM64 images, eliminating the need to maintain separate build specifications for different architectures.

The following diagram illustrates the YAML configuration flow through the CleanStart build pipeline:

graph LR    A["image.yaml<br/>Git Repository"] -->|Contents| B["Metadata<br/>name, version<br/>owner"]     A -->|Contents| C["Base Image<br/>python 3.12<br/>alpine, glibc"]     A -->|Contents| D["Dependencies<br/>fastapi, uvicorn<br/>sqlalchemy"]     A -->|Contents| E["Build Flags<br/>FIPS, hardening<br/>reproducible"]     A -->|Contents| F["Security<br/>scan_depth<br/>vex_required"]     B -->|Input| G["CleanStart<br/>Build Pipeline"]     C -->|Input| G    D -->|Input| G    E -->|Input| G    F -->|Input| G     G -->|Validate| H["Policy<br/>Checks"]     H -->|Verify| I["FIPS<br/>Compliance"]    H -->|Verify| J["License<br/>Compliance"]    H -->|Verify| K["Dependency<br/>Resolution"]     I -->|Pass| L["Generate<br/>Image"]    J -->|Pass| L    K -->|Pass| L     L -->|AMD64| M["Build<br/>x86_64"]    L -->|ARM64| N["Build<br/>aarch64"]     M -->|Artifact| O["Signed<br/>Image"]    N -->|Artifact| O     O -->|Attestation| P["SBOM"]    O -->|Attestation| Q["Provenance"]    O -->|Attestation| R["Signature"]     P -->|Register| S["Container<br/>Registry"]    Q -->|Register| S    R -->|Register| S     style A fill:#ccffcc    style G fill:#99ccff    style O fill:#99ff99    style S fill:#ffff99

Basic Structure

Minimal Configuration

name: my-appbase_language: pythonversion: 3.12

Result: Python 3.12 image with no additional packages (base only).

Standard Configuration

name: api-servicedescription: "FastAPI microservice"base_language: pythonversion: 3.12.1packages:  fastapi: 0.104.1  uvicorn: 0.24.0  sqlalchemy: 2.0.23

Result: Python 3.12.1 image with FastAPI, Uvicorn, SQLAlchemy.

Complete Configuration

# metadataname: api-servicedescription: "Production FastAPI microservice"owner: api-platform-teamversion: v1.0.0documentation_url: "https://wiki.example.com/api-service" # base image definitionbase_language: pythonlanguage_version: 3.12.1base_os: linux-glibc  # or linux-musl, linux-alpine # dependenciespackages:  # Python packages (PyPI)  fastapi: 0.104.1  uvicorn: 0.24.0  sqlalchemy: 2.0.23  pydantic: 2.5.0   # System packages (apt-get)  system_packages:    - curl    - ca-certificates # build configurationbuild_flags:  fips: true                # Enable FIPS compilation  hardening: maximum        # Security compilation flags  optimization: O2          # Optimization level  strip_binaries: true      # Remove debug symbols  reproducible: true        # Ensure bit-for-bit reproducibility # security and compliancesecurity:  scan_depth: full          # Full source code analysis  vex_required: true        # Generate VEX attestations  license_check: true       # Verify license compliance # testing and verificationtesting:  enabled: true  run_all_tests: true       # Run full 78-test suite # deployment settingsmetadata:  labels:    team: api-platform    environment: production    compliance: pci-dss  annotations:    maintainer: "api-team@example.com"    support_url: "https://slack.example.com/api-platform"

Language and Version Selection

Supported Languages

Language

Versions

Examples

Python

3.8 - 3.13

3.12.1, 3.11.8, 3.10.14

Node.js

16 - 21

20.10.0, 18.19.0, 21.6.0

Go

1.19 - 1.22

1.21.5, 1.20.12

Java

11, 17, 21

21-jdk, 17-jdk, 11-jdk

Rust

1.70+

1.74.1, 1.73.0

Ruby

2.7 - 3.2

3.2.2, 3.1.4, 3.0.6

PHP

7.4 - 8.3

8.2.14, 8.1.26

Version Specification

# Exact versionlanguage_version: 3.12.1 # Minor version (resolves to latest patch)language_version: 3.12 # Latest stablelanguage_version: latest # Rangelanguage_version: ">=3.10,<3.13"

Base OS Options

# Linux with glibc (most common, larger)base_os: linux-glibc # Linux with musl (smaller, BSD compatibility)base_os: linux-musl # Alpine (minimal, small)base_os: linux-alpine

Package Management

Python (PyPI)

packages:  # Exact version  fastapi: 0.104.1   # Version range  sqlalchemy: ">=2.0.0,<2.1.0"   # Extras (optional dependencies)  pydantic: { version: 2.5.0, extras: ["email", "validator"] }   # Git source (advanced)  custom-lib: { git: "https://github.com/org/repo", ref: "main" }

Node.js (npm)

packages:  # npm package  express: 4.18.2   # With version range  axios: "^1.6.0"   # Extras/peer dependencies specified automatically  react: 18.2.0  react-dom: 18.2.0

Go

packages:  # Go module  github.com/gin-gonic/gin: v1.9.1   # Indirect dependencies managed automatically  github.com/golang/protobuf: v1.5.3

Java

packages:  # Maven coordinates  "org.springframework.boot:spring-boot-starter-web": 3.1.5  "com.google.guava:guava": 32.1.3-jre

Rust

packages:  # Crates.io dependencies  actix-web: 4.4.1  tokio: { version: 1.35.0, features: ["full"] }

System Packages

packages:  system_packages:    - curl         # HTTP client    - wget         # Download tool    - git          # Version control    - ca-certificates  # TLS/SSL certs    - openssh-client   # SSH client

Build Flags and Configuration

Security Hardening

build_flags:  hardening: maximum        # Full hardening  # Equivalent to:  # -fstack-protector-all   (stack overflow protection)  # -D_FORTIFY_SOURCE=2     (bounds checking)  # -fPIE                   (position-independent executable)  # -Wl,-z,relro            (read-only relocation sections)  # -Wl,-z,now              (bind symbols at load time)

FIPS Compliance

build_flags:  fips: true                # Enable FIPS compilation  # Compiles cryptographic libraries with FIPS algorithms only  # Disables MD5, SHA1, DES (deprecated algorithms)  # Enforces NIST-approved algorithms

Optimization

build_flags:  optimization: O2          # Standard optimization (speed + size)  # Other options:  # O0 - No optimization (debugging)  # O1 - Light optimization  # O3 - Aggressive optimization (larger binary)  # Os - Optimize for size

Binary Stripping

build_flags:  strip_binaries: true      # Remove debug symbols  # Result: Smaller image (~20% reduction)  # Tradeoff: Cannot debug with symbols

Reproducibility

build_flags:  reproducible: true        # Ensure bit-for-bit reproducibility  # Removes build timestamps, random UUIDs, etc.  # Allows: Rebuild 6 months later → identical image

Dependency Configuration

Transitive Dependency Control

# Allow all transitive dependencies (default)dependency_mode: auto # Pin transitive dependencies to specific versionsdependency_mode: pinneddependencies:  requests:          # Transitive of some package    version: 2.31.0    pinned: true

Optional Dependencies

packages:  # Include optional dependencies  pydantic:    version: 2.5.0    extras:      - email      # Email validation support      - validator  # Custom validators   # OR exclude optional dependencies  sqlalchemy:    version: 2.0.0    exclude_extras: true  # No optional features

Pre-Release Handling

allow_prerelease: false   # Never use pre-release versions# Options:# false - Only stable releases (recommended for production)# true  - Allow pre-releases# "alpha-only" - Only alpha/beta, not RC

Metadata and Labeling

Container Labels

metadata:  labels:    version: "1.0.0"    team: api-platform    environment: production    compliance: pci-dss    sla: "99.9%"

Annotations

metadata:  annotations:    description: "Production FastAPI microservice"    documentation: "https://wiki.example.com/api-service"    maintainer: "api-team@example.com"    support_slack: "#api-platform"    oncall_runbook: "https://runbooks.example.com/api-outage"

Image Registry Settings

registry:  primary: registry.cleanstart.io  mirrors:    - docker.io    - ghcr.io    - gcr.io/$PROJECT_ID  auth_required: true

Security and Compliance

Vulnerability Scanning

security:  scan_depth: full          # Deep analysis (4 layers)  # Options:  # full    - AST + binary + runtime + usage analysis  # binary  - Binary + runtime analysis (faster)  # quick   - Package version only (fastest, less accurate)   cve_threshold: critical   # Alert on critical+ CVEs  # Options:  # critical  - Only CVSS 9.0+  # high      - CVSS 7.0+  # medium    - CVSS 5.0+  # low       - All CVEs   vex_required: true        # Generate VEX attestations

License Compliance

security:  license_check: true  allowed_licenses:    - MIT    - Apache-2.0    - BSD-3-Clause    - GPL-2.0-only   forbidden_licenses:    - AGPL-3.0  # Copyleft license    - SSPL      # Server-side public license

FIPS and Regulatory

security:  fips: true                # Build with FIPS algorithms  hipaa_ready: true         # HIPAA-compliant compilation  pci_dss: true             # PCI-DSS compliance

Testing and Validation

Test Configuration

testing:  enabled: true  run_all_tests: true       # Run all 78 tests  # Or specify subset:  # run_tests:  #   - security  #   - functionality  #   - compliance   performance_threshold:    boot_time: 2000ms       # Max 2 second boot time    memory_baseline: 256MB  # Baseline memory usage

Custom Tests

testing:  custom_tests:    - name: "API health check"      command: "curl http://localhost:8000/health"      expected_output: "healthy"      timeout: 5s     - name: "Database connection"      command: "python -c 'import db; db.connect()'"      timeout: 10s

Policy and Governance

Enforcement Policies

policies:  enforce_pinned_versions: true     # All versions must be pinned  no_latest_tags: true              # No "latest" tags allowed  require_documentation: true        # Description required  require_owner: true                # Owner must be specified  disable_root: true                 # Image cannot run as root

Change Approval

governance:  require_pr_approval: true          # PR review required  require_security_review: true      # Security team approval  require_cve_clearance: true        # CVE check before merge  reviewers:    - security-team@example.com    - platform-team@example.com

Advanced: Multi-Variant Configuration

Build Multiple Variants from One Config

# Base config applies to all variantsname: web-apibase_language: pythonversion: 3.12 # Define variants with overridesvariants:  production:    build_flags:      fips: true      hardening: maximum      optimization: O2    packages:      fastapi: 0.104.1      uvicorn: 0.24.0   staging:    build_flags:      fips: false      optimization: O1    packages:      fastapi: 0.104.1      uvicorn: 0.24.0   development:    build_flags:      hardening: none      optimization: O0    packages:      fastapi: 0.104.1      uvicorn: 0.24.0      pytest: 7.4.3      ipython: 8.18.1

Result: Three images from one config (web-api:production, web-api:staging, web-api:development).

Configuration Validation

Pre-Build Validation

clnstrt-cli validate images/api-service.yaml # Checks:# - Syntax is valid YAML# - All required fields present# - Versions are resolvable# - Policies are met# - Security configuration valid# Result: PASS or list of errors

Policy Validation

clnstrt-cli validate images/api-service.yaml --policy security-policy.yaml # Additional checks:# - No forbidden packages# - No forbidden licenses# - Security flags comply with policy# - Image size within limits

Configuration Best Practices

1. Pin All Versions

# ❌ BAD: Unpinned, unpredictablepackages:  fastapi: "*"  uvicorn: "latest" # ✅ GOOD: Pinned, reproduciblepackages:  fastapi: 0.104.1  uvicorn: 0.24.0

2. Document Everything

# ✅ GOOD: Well documentedname: api-servicedescription: "Production FastAPI microservice handling payment processing"documentation_url: "https://wiki.example.com/api-service"owner: api-platform-team

3. Use Build Flags for Security

# ✅ GOOD: Hardening enabledbuild_flags:  hardening: maximum  fips: true  strip_binaries: true # ❌ BAD: No hardeningbuild_flags: {}

4. Enforce Policies

# ✅ GOOD: Policies definedpolicies:  no_untagged_versions: true  require_owner: true  license_check: true

5. Version Control Configuration

# Store config in Gitgit add images/api-service.yamlgit commit -m "Update FastAPI to 0.104.1 (security patch)" # Every change is tracked, reviewable, auditable

Examples

Python FastAPI

name: api-servicedescription: "FastAPI microservice with database"base_language: pythonversion: 3.12.1packages:  fastapi: 0.104.1  uvicorn: 0.24.0  sqlalchemy: 2.0.23  psycopg2-binary: 2.9.9build_flags:  fips: true  hardening: maximumsecurity:  scan_depth: full  vex_required: truemetadata:  owner: platform-team  labels:    team: backend    environment: production

Node.js Express

name: web-appbase_language: nodeversion: 20.10.0packages:  express: 4.18.2  axios: 1.6.2  morgan: 1.10.0  dotenv: 16.3.1build_flags:  hardening: maximum  optimization: O2metadata:  owner: frontend-team

Go API

name: golang-apibase_language: goversion: 1.21.5packages:  github.com/gin-gonic/gin: v1.9.1  github.com/golang-jwt/jwt: v5.1.0build_flags:  hardening: maximum  fips: truesecurity:  license_check: true

Next Steps

Understand image construction: Image Construction Overview. Learn about multi-architecture builds: Multi-Arch Build Strategy. Explore the builder pattern: Builder Pattern Dev-Prod. Start building: Quick Start.

Key Insight

YAML configuration = versioned, reviewed, auditable image definitions.

Instead of a black box Dockerfile, you have a declarative, version-controlled specification that can be reviewed by security teams, validated by policies, and reproduced identically.