2026-07-31 23:02:28 +00:00
2026-07-31 23:02:28 +00:00
2026-07-31 23:02:28 +00:00
2026-07-31 23:02:28 +00:00

@serve.zone/workloadinit

@serve.zone/workloadinit is the static serve.zone workload launcher that injects file-delivered secrets into a process environment immediately before replacing itself with that process. The npm package also exposes one diagnostic path resolver; it does not install or execute the binary from TypeScript.

Issue Reporting and Security

For reporting bugs, issues, or security vulnerabilities, please visit community.foss.global/. This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a code.foss.global/ account to submit Pull Requests directly.

Protocol V1

The only workload invocation is:

workloadinit run --map /run/serve.zone/workloadinit-map-v1.json -- <command> [args...]

The map must be a canonical IWorkloadInitEnvironmentMapV1 from @serve.zone/interfaces 24. It contains exactly schemaVersion, manifestId, manifestDigest, and one to 256 sorted entries, in that property order. Each entry contains exactly variableName, resource, and source, also in that order. Duplicate JSON keys, unknown or reordered fields, malformed scalar types, noncanonical identifiers, duplicate variables/resources/sources, unsorted entries, and any source outside /run/serve.zone/secrets/<resource> are rejected.

The fixed exit status contract is:

Status Meaning
0 help, version, or successful install; successful run transfers control and preserves the workload's eventual status
64 CLI usage
65 map open, metadata, read, or validation failure
66 secret source metadata, read, UTF-8, or NUL failure
69 installation failure
70 executable resolution or execve failure

Failure output contains only a stable error class and code. It never includes paths, argv, map content, environment content, or secret values.

Security Boundary

run is Linux-only and fails closed if openat2 with RESOLVE_BENEATH | RESOLVE_NO_SYMLINKS | RESOLVE_NO_MAGICLINKS is unavailable. It opens / once, resolves the fixed map and every declared secret beneath that descriptor, uses O_NOFOLLOW, reads each already-open descriptor exactly once, and compares pre/post fstat identity and mutation metadata.

The map must be a root-owned regular file with exact mode 0444 and is bounded to 1 MiB. Secret sources must be regular files with exact mode 0400 or 0440, can have any owner, and are bounded to 500 KiB. Secret bytes must be strict UTF-8 without NUL. Newlines and every other byte are preserved; values are never trimmed.

The launcher snapshots raw inherited environ entries without Unicode conversion, preserving unaffected bytes, duplicates, and order. It removes every inherited occurrence of a mapped variable and appends exactly one replacement per map order. Executable resolution uses the original inherited PATH before overrides: slash-containing argv[0] is used exactly; slash-free names use the first inherited PATH, /bin:/usr/bin when absent, and current directory for empty components. execve receives the original argv bytes and the rebuilt environment directly, without a shell. A successful handoff preserves PID and signal semantics.

Controlled secret, source, and rebuilt-environment buffers use zeroize on failure paths. This cannot guarantee erasure of copies held by the kernel, the executed process, allocator internals, prior reallocations, crash dumps, swap, or compiler/runtime machinery. Successful execve replaces the process image instead of running cleanup code.

Install Lifecycle

The helper image has one installation command:

workloadinit install

It installs its authenticated running executable at:

/opt/serve.zone/runtime-assets/workloadinit/v1/workloadinit

The installer must run as root with root group. It traverses and creates only those fixed parent components through held directory descriptors, and rejects any component that is not root-owned/root-group or is group/world writable. It removes only canonical stale temporary names from an earlier interrupted install, writes a cryptographically random same-directory temporary file, synchronizes it, sets exact mode 0555, verifies root ownership, one link, bytes, SHA-256, and metadata, atomically renames it over the target, and synchronizes the parent directory. An identical root-owned single-link target is left unchanged. A different, symlinked, hardlinked, or wrongly owned target is atomically replaced so a consumer can deploy protocol-compatible security patches. The consumer's digest-pinned OCI image controls downgrade and version policy; no sidecar or symlink supplies trust.

Run one install job per node-local runtime-assets volume before workloads start. Mount that volume read-write only into the install job and read-only into workloads. The released image is FROM scratch, contains only /workloadinit, and supports linux/amd64 and linux/arm64.

Coreflow and Onebox integration is future consumer work. This package release does not claim an end-to-end secret-delivery deployment.

Signed Image Release

WorkloadInit images use only immutable v<package-version> tags. latest, rebuild-on-push, and automatic Docker publication are intentionally disabled. The Git and npm release happens first through the configured gitzone release -y workflow. Docker publication is a separate, signature-gated continuation that must reuse one persisted TSDocker candidate.

The release statement and validators come from @serve.zone/interfaces/runtime 24. The statement has exactly one subject: the SHA-256 digest of the candidate root OCI index, which publication later requires and re-verifies remotely. That digest transitively binds both runnable platform manifests, their configs and layers, and the exact /workloadinit bytes. The release verifier independently checks that graph for linux/amd64 and linux/arm64, including TSDocker source/version/revision labels and paired BuildKit provenance descriptors.

Candidate Preparation

After the clean source release commit and v<version> Git tag exist, build one candidate and keep the same TSDOCKER_SESSION_ID for every subsequent command:

export VERSION="1.1.0"
export TSDOCKER_SESSION_ID="workloadinit-v${VERSION}"
export RELEASE_DIR=".nogit/workloadinit-release/v${VERSION}"

mkdir -p "$RELEASE_DIR"
pnpm run release:prepare -- --version "$VERSION"

export CANDIDATE_DIGEST="$(jq -r '.workloadInitImageIndexDigest' "$RELEASE_DIR/workloadinit-v${VERSION}.candidate-evidence.json")"
test -n "$CANDIDATE_DIGEST"

release:prepare first requires the exact branch and annotated tag on Git origin, plus identical package integrity from Verdaccio and npmjs. It records the build-tool versions and creates an exclusive value-free build lock before invoking TSDocker, so concurrent or interrupted preparation cannot start a second build. After the sole clean tagged-source build, it writes a candidate checkpoint before inspection. It then starts the persisted local TSDocker registry, verifies the exact candidate graph without extracting its filesystem, and executes each platform-manifest digest's /workloadinit --version entrypoint in a read-only, networkless, capability-free container. Finally it writes a canonical no-newline statement plus candidate evidence beneath .nogit/. It rejects version 1.0.0 permanently and refuses to build over completed ceremony artifacts. If inspection is interrupted, rerunning the same command with the same session resumes from the checkpoint. If interruption occurs before a digest exists, the retained build lock fails closed and requires explicit operator investigation; the command never starts another build automatically.

Signing Ceremony

Signing requires a separately authorized encrypted ECDSA P-256 operator key. Never place a private key in this repository, .nogit/, a release asset, a command argument, or an environment variable. The public key, statement, bundle, and factual receipts contain no secret material.

Use the pinned official Cosign v3.1.2 Linux amd64 binary:

mkdir -p .nogit/tools
curl -fL 'https://github.com/sigstore/cosign/releases/download/v3.1.2/cosign-linux-amd64' -o .nogit/tools/cosign-v3.1.2-linux-amd64
printf '%s  %s\n' 'f7622ed3cf22e55e1ae6377c080979ff77a22da9981c11df222a2e444991e7cf' '.nogit/tools/cosign-v3.1.2-linux-amd64' | sha256sum -c -
chmod 0755 .nogit/tools/cosign-v3.1.2-linux-amd64

With operator-controlled paths for the encrypted key and its public key:

export COSIGN=".nogit/tools/cosign-v3.1.2-linux-amd64"
export STATEMENT="$RELEASE_DIR/workloadinit-v${VERSION}.statement.json"
export BUNDLE="$RELEASE_DIR/workloadinit-v${VERSION}.sigstore.json"
export PUBLIC_KEY="/operator-controlled/path/workloadinit-release.pub"
export ENCRYPTED_KEY="/operator-controlled/path/workloadinit-release.key"

"$COSIGN" attest-blob \
  --statement "$STATEMENT" \
  --bundle "$BUNDLE" \
  --key "$ENCRYPTED_KEY" \
  --tlog-upload=false \
  --use-signing-config=false \
  --yes

pnpm run release:key-id -- --public-key "$PUBLIC_KEY"

Record the printed sha256:<SPKI DER digest> as KEY_ID. The --tlog-upload=false deprecation warning is expected; --use-signing-config=false and the explicit encrypted key keep the ceremony independent of OIDC, Fulcio, Rekor, ambient Sigstore trust, and network signing services.

Digest-Fenced Publication

Publication repeats local graph, per-platform executable, and signature verification before it pushes. It then resolves the remote version tag, requires the exact candidate digest, and re-verifies the complete remote graph:

export KEY_ID="sha256:<operator-verified-spki-digest>"

pnpm run release:docker -- \
  --version "$VERSION" \
  --candidate-digest "$CANDIDATE_DIGEST" \
  --statement "$STATEMENT" \
  --bundle "$BUNDLE" \
  --public-key "$PUBLIC_KEY" \
  --expected-key-id "$KEY_ID" \
  --cosign "$COSIGN"

The command never builds. Its only TSDocker publication operation is digest-fenced push --no-build; candidate execution uses each exact local platform-manifest digest rather than a mutable tag. If Git/npm publication succeeded but Docker publication did not, preserve the TSDocker session and retry with the same candidate digest; never rebuild under the existing version.

The detached bundle and release assets are untrusted transport. WorkloadInit verifies cryptographic consistency and reports the signer SPKI ID, but it does not authorize that signer. Cloudly's private policy exclusively owns trusted-key pinning, rotation, revocation, policy generation, and release approval. A publication receipt is factual evidence only and is never a Cloudly approval.

TypeScript API

Install with pnpm:

pnpm add @serve.zone/workloadinit

Resolve the packaged binary for diagnostics or tests:

import { getWorkloadInitBinaryPath } from '@serve.zone/workloadinit';

const binaryPath = getWorkloadInitBinaryPath();

getWorkloadInitBinaryPath() supports Linux x64 and arm64, verifies that the selected packaged file exists, and performs no installation.

Audited Unsafe Boundaries

Rust unsafe is confined to small Linux ABI boundaries: openat2 and descriptor syscalls, raw inherited environ traversal, execve, and test-only fork/wait helpers. Every pointer passed to the kernel is backed by a live NUL-terminated buffer, every inherited environment pointer is copied before use, and every returned descriptor is immediately placed under owned RAII management.

This repository contains open-source code licensed under the MIT License. A copy of the license can be found in license.md.

Please note: The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.

Trademarks

This project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.

Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.

Company Information

Task Venture Capital GmbH
Registered at District Court Bremen HRB 35230 HB, Germany

For any legal inquiries or further information, please contact us via email at hello@task.vc.

By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.

S
Description
No description provided
Readme
318 KiB
Languages
TypeScript 60.7%
Rust 39.3%