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:#ffff99Basic Structure
Minimal Configuration
name: my-appbase_language: pythonversion: 3.12Result: 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.23Result: 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-alpinePackage 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.0Go
packages: # Go module github.com/gin-gonic/gin: v1.9.1 # Indirect dependencies managed automatically github.com/golang/protobuf: v1.5.3Java
packages: # Maven coordinates "org.springframework.boot:spring-boot-starter-web": 3.1.5 "com.google.guava:guava": 32.1.3-jreRust
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 clientBuild 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 algorithmsOptimization
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 sizeBinary Stripping
build_flags: strip_binaries: true # Remove debug symbols # Result: Smaller image (~20% reduction) # Tradeoff: Cannot debug with symbolsReproducibility
build_flags: reproducible: true # Ensure bit-for-bit reproducibility # Removes build timestamps, random UUIDs, etc. # Allows: Rebuild 6 months later → identical imageDependency 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: trueOptional 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 featuresPre-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 RCMetadata 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: trueSecurity 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 attestationsLicense 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 licenseFIPS and Regulatory
security: fips: true # Build with FIPS algorithms hipaa_ready: true # HIPAA-compliant compilation pci_dss: true # PCI-DSS complianceTesting 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 usageCustom 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: 10sPolicy 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 rootChange 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.comAdvanced: 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.1Result: 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 errorsPolicy 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 limitsConfiguration Best Practices
1. Pin All Versions
# ❌ BAD: Unpinned, unpredictablepackages: fastapi: "*" uvicorn: "latest" # ✅ GOOD: Pinned, reproduciblepackages: fastapi: 0.104.1 uvicorn: 0.24.02. Document Everything
# ✅ GOOD: Well documentedname: api-servicedescription: "Production FastAPI microservice handling payment processing"documentation_url: "https://wiki.example.com/api-service"owner: api-platform-team3. 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: true5. 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, auditableExamples
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: productionNode.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-teamGo 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: trueNext 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.
