-
Notifications
You must be signed in to change notification settings - Fork 0
Scripts Reference
Every buildable Go command and every script in the repository, what it does, what it needs, and who calls it.
The builder CLI itself. Full flag/exit-code reference:
CLI Reference. Backed by internal/oci (see
Architecture and OCI Layout).
A tiny, stdlib-only Go HTTP API (net/http, log/slog - no dependencies)
used as a fixture, not a product: /healthz, /ping, /metrics
(Prometheus text format), structured JSON request logging. Built by
scripts/local/build-macos-image.sh and
by ci-microvm.yml (see Testing and CI/CD) -
it exists so both consumers exercise the exact same known-good payload
without duplicating a hand-written HTTP app in three different shell
heredocs.
A tiny stdlib-only Go binary that runs as PID 1 inside a microVM, nowhere else. What it does:
- Execs exactly one child process (the OCI image's declared entrypoint, passed as its own arguments).
- Forwards
SIGTERM/SIGINTto that child. - Waits for it to exit.
- Calls
syscall.Reboot(LINUX_REBOOT_CMD_POWER_OFF)to cleanly power the VM off.
It deliberately does not reap unrelated reparented orphan processes - general-purpose init duties are out of scope for a single-process VM image.
Testing note: the real poweroff() (Linux-only, behind a
//go:build linux file, poweroff_linux.go) is never called from any
test, on any platform - doing so on a real Linux CI runner would attempt
to power that runner off. Instead, realMain takes the poweroff function
as an injected parameter, so tests can pass a fake and assert it was
called without ever executing the real syscall. poweroff_other.go
(//go:build !linux) is a safe no-op stub so the package still builds and
tests cleanly on non-Linux dev machines. The process-supervision logic
(run, execChild) is tested against real subprocesses (sh -c,
sleep) on whatever host runs go test - never inside a VM, never as
PID 1, so this is safe on any developer machine or CI runner.
scripts/ci/verify-elf.sh <binary> <amd64|arm64>Confirms a binary is a static ELF64 executable for the requested
architecture, using readelf: checks Class: ELF64, checks the machine
type matches the requested architecture (Advanced Micro Devices X86-64/
AMD x86-64 for amd64, AArch64 for arm64), and rejects any binary
with a PT_INTERP program header - the marker of a dynamically-linked
executable that needs an interpreter (ld.so) at runtime. Prints
ELF_VALIDATION_OK ... on success, ELF_VALIDATION_FAILURE: ... (to
stderr) and a non-zero exit on any failure. Used by ci-quality.yml and
scripts/ci/build-verified-layout.sh.
scripts/ci/build-verified-layout.sh OUTPUT BINARY ARCHThe shared "build the CLI, build a layout, verify it" sequence: builds
cmd/oci-builder deterministically (-trimpath -buildvcs=true) for
ARCH, runs verify-elf.sh against it, runs it against itself
(-created 1970-01-01T00:00:00Z) to produce OUTPUT, then runs
scripts/ci/verify-oci-layout.py OUTPUT. Used by ci-oci-validation.yml
and ci-reproducibility.yml.
python3 scripts/ci/verify-oci-layout.py <layout-directory>A strict, dependency-free (standard library only) re-verifier of a single-platform OCI layout - it does not trust or reuse any of the Go builder's own internal logic, it re-derives everything from the raw bytes on disk:
- the
oci-layoutmarker file's exact bytes, -
index.jsonhas schema version 2 and exactly one manifest, - every descriptor (manifest, config, layer): digest format, digest actually matches the blob's content, size matches, media type matches,
- the platform is
linux/amd64orlinux/arm64, - the config's
os/architecturematch the index descriptor's platform, - the config has exactly one
rootfs.diff_idand exactly oneEntrypointelement, - the layer decompresses, its uncompressed hash matches the declared
diff_id, every tar entry name is safe (no absolute paths, no..traversal, no duplicate names, no symlinks/hardlinks/device/FIFO entries), and the declared entrypoint path is actually present in it, - the blob directory contains exactly the three expected blobs - no extra, no missing, no non-regular files.
Prints OCI_VALIDATION_OK on success; any failure prints
OCI_VALIDATION_FAILURE: <reason> to stderr and exits 1. This is also
what Debugging Minimal Containers
recommends for inspecting a layout standalone, with nothing else running.
python3 scripts/ci/negative-oci-layout.py <verifier-script> <good-layout-directory>Proves the verifier isn't just optimistic - it copies a known-good layout into a temp directory seven times, applies one hostile mutation per copy, and asserts the verifier rejects every single one:
| Case | Mutation |
|---|---|
missing-blob |
deletes one blob file |
corrupted-blob |
appends a byte to one blob |
truncated-layer |
truncates the layer blob to 8 bytes |
invalid-index |
replaces index.json with an empty-manifests document |
extra-blob |
adds a blob that isn't referenced by anything |
symlink-blob |
replaces a blob with a symlink to /etc/passwd
|
invalid-media-type |
changes the manifest descriptor's mediaType
|
If the verifier ever accepts one of these (a "false negative"), this
script exits non-zero with a clear message identifying which case failed
to be rejected. Used by ci-oci-validation.yml and ci-quality.yml.
python3 scripts/ci/verify-attestation-index.py PUBLISHED_INDEX_JSONOnly used in ci-release.yml's publish job, against the published
registry index (fetched via docker buildx imagetools inspect --raw, not
the local build layout). Confirms the index contains at least one manifest
descriptor annotated vnd.docker.reference.type: attestation-manifest
with a valid sha256: digest - i.e. that BuildKit's SBOM/provenance
attestation actually made it into what was published, not just that the
docker buildx build --provenance=... --sbom=... command exited zero.
python3 scripts/ci/verify-workflows.pyThe CI-configuration policy checker - see
Testing and CI/CD for the
full rule set. Notably parses YAML via a ruby -ryaml -rjson subprocess
rather than a Python YAML library, specifically to avoid a PyYAML
dependency. Requires ruby on PATH.
See Local Development (Podman/macOS) for the full walkthrough.
-
scripts/local/bootstrap.shandscripts/local/bootstrap.ps1build all four Go commands into an isolated binary environment:# Linux/macOS scripts/local/bootstrap.sh source .platform-factory/activate # Windows PowerShell .\scripts\local\bootstrap.ps1 . .\.platform-factory.ps1
The environment contains
secure-oci,oci-builder,example-service, andmicrovm-init, anenvironment.jsoninventory, and activation scripts for POSIX, PowerShell, and CMD. It is not a Python virtualenv and does not alter the system.Cross-platform and installation examples:
scripts/local/bootstrap.sh --target linux/amd64 --env dist/linux scripts/local/bootstrap.sh --target darwin/arm64 --env dist/macos scripts/local/bootstrap.sh --target windows/amd64 --env dist/windows scripts/local/bootstrap.sh --install "$HOME/.local"PowerShell uses
-TargetOS,-TargetArch,-Environment,-InstallPrefix, and-Clean. POSIX uses--target,--env,--install, and--clean. Both refuse unsafe or implicit replacement, compile withCGO_ENABLED=0, inject the Git version intosecure-oci, and restore or scope all Go target environment variables.--install PREFIXcopies only intoPREFIX/bin; neither script downloads or installs Docker, Podman, Skopeo, Cosign, Syft, QEMU, Kubernetes tooling, or other system packages. -
scripts/local/build-macos-image.sh- buildscmd/example-service, turns it into a layout, builds a local container image from it with Podman. Touches nothing in the repository working tree. -
scripts/local/Dockerfile- a local-only, single-Alpine-stage variant of the repository rootDockerfile(same checks, fewer layers, faster local rebuilds; same entrypoint-symlink derivation, not hardcoded). -
scripts/local/package-dynamic-binary.shscripts/local/package-dynamic-binary.sh BINARY OUTPUT [ENTRYPOINT]
Runs
lddagainstBINARY, turns every real dependency line into an-extra-file DEST=SOURCE(preserving each dependency's own absolute path unchanged - the guest's dynamic linker looks for libraries at their normal system paths, so keeping the same path sidesteps having to reconstruct a library directory layout), then invokescmd/oci-builder. Errors loudly on an unresolved dependency (lddreporting=> not found) rather than silently producing a layout that would fail at runtime. Must run on Linux, matching the binary's own architecture -lddtraces the binary by asking its own dynamic linker to report what it would load, which requires actually being able to run it (or a faithful architecture match). This is the automated version of what CLI Reference shows doing by hand, and is what makes a genuinely legacy, dynamically-linked binary bootable through this project at all - DLL hell's quieter Linux cousin, resolved once at build time instead of argued about at runtime.
See MicroVM Support for the full walkthrough.
-
scripts/microvm/lib-arch.sh- sourced, not executed, by every other script in this directory. Mapsuname -mto this project'samd64/arm64convention and the matching QEMU binary (qemu-system-x86_64/qemu-system-aarch64) - the single source of truth for that mapping, socheck-kvm.sh,build-kernel.sh, andrun-microvm.shcan't disagree with each other about it. -
scripts/microvm/check-kvm.sh- non-destructive, no-sudo capability check (host OS, architecture, virtualization support,/dev/kvmexistence and permissions, required binaries onPATH). Never installs or changes anything. -
scripts/microvm/build-kernel.shscripts/microvm/build-kernel.sh <amd64|arm64> OUTPUT_KERNEL_IMAGE
Downloads Linux 6.12.98 source from
cdn.kernel.org, verifies it against a pinned SHA-256 before extracting anything, mergeskernel-common.configand the requested architecture'skernel-<arch>.configonto the stock arch defconfig via the kernel's ownscripts/kconfig/merge_config.sh(which itself non-interactively resolves every remaining symbol viamake alldefconfig- not a manualoldconfigstep), then buildsbzImage(amd64) orImage(arm64). Refuses to run on a non-Linux host, and refuses to build a kernel for an architecture that doesn't match the current host (kernel builds are never cross-compiled here - KVM can't accelerate a mismatched guest anyway, so there'd be no point). Skips the build entirely if the output file already exists, unlessFORCE_REBUILD=1is set. Also writeskernel.provenance.json(version, source URL, source and resolved-config checksums) andkernel.sbom.cdx.json(a CycloneDX 1.5 SBOM for the kernel component, with a deterministic UUIDv5 serial number so it stays reproducible) next to the kernel image - see MicroVM Support. -
scripts/microvm/assemble-initramfs.shscripts/microvm/assemble-initramfs.sh LAYER_TAR_GZ INIT_BINARY OUTPUT_INITRAMFS_GZ
Extracts an OCI layer tar, adds a single init binary at
/sbin/init, and packs the result into a gzip-compressed cpio (newc) initramfs - byte-for-byte reproducible given the same inputs (tar --delay-directory-restore,cpio --reproducible, a fixed sorted entry order, and the freshly-added init binary's mtime pinned to epoch 0). Factored out ofrun-microvm.shsoci-microvm.ymlcan call it twice and diff the output. -
scripts/microvm/kernel-common.config/kernel-amd64.config/kernel-arm64.config- Kconfig fragments.kernel-common.configforces only what every architecture needs built-in (initramfs support, virtio-net-pci, IP autoconfiguration, devtmpfs auto-mount, TTY/proc/sysfs); the per-arch files add exactly what differs (ACPI + 8250 serial on amd64; generic PCI host controller + PL011 serial on arm64). Everything else is left at the arch defconfig's own default - an unbuilt-in (=m) driver costs nothing here because the build only ever runs the kernel-image make target, nevermodules. -
scripts/microvm/run-microvm.sh- the main entry point; see MicroVM Support for full usage and environment variables.
-
Dockerfile(repository root) - see Dockerfile Consumer. -
COMPLIANCE.md- the automated-evidence matrix; see Security Model. -
SECURITY.md- currently an unfilled template; see Security Model.
© 2026 CYPT71
platform-factory
Core
- Architecture and OCI Layout
- Next-generation Architecture
- Architecture Decision Records
- Security Model
- Threat Model and Residual Risks
- Independent Security Review Process
- CLI Reference
- Project Configuration and Dependency Freezing
- mTLS Configuration
- Meine Graal
CI/CD
Running an image
- Production Adoption Guide
- Dockerfile Consumer
- Local Dev (Podman/macOS)
- MicroVM Support
- MicroVM Administration
- Large-image streaming
Operating