0012 — Artifacts use content-addressed upload
- Status: accepted
- Date: 2026-08-06
- Owners: Takoform maintainers
Context
Decision 0002 made artifact sources credential-free HTTPS URLs fetched by the host. That keeps secrets out of state, but it forces every deployment to publish a world-readable artifact endpoint, makes the host's fetch path a hidden availability dependency, leaves media-type and layout validation implicit, and cannot express a multi-module worker bundle (main module, additional modules, WASM, source maps) as one verified unit.
Decision
The v1alpha3 lane replaces external artifact URLs with a content-addressed upload API on the host:
POST /artifacts/uploads
PUT /artifacts/uploads/{uploadId}/blobs/{sha256}
POST /artifacts/uploads/{uploadId}/commit
GET /artifacts/{manifestDigest}
HEAD /artifacts/blobs/{sha256}
DELETE /artifacts/uploads/{uploadId}The client computes blob digests locally, asks the host which blobs are missing, uploads only those, and commits a canonical manifest. The host verifies size, digest, and media type per blob, then returns an immutable manifest digest. Desired state references only that manifest digest; raw code bytes and upload endpoints never enter Terraform state.
An artifact manifest is a typed, canonical document (for example artifacts.takoform.com/v1alpha1 WorkerBundle with mainModule and a modules[] list of name, media type, size, digest). Media types are closed per manifest kind. Archives are transport only; a tar or zip byte stream is never a semantic identity.
Hosts reject: duplicate module names, absolute paths, .., backslashes, NUL, invalid UTF-8 names, unsupported media types, size or digest mismatches, file count and total-size overruns, a missing main module, source maps whose target module is absent, and archive bombs.
Uploads are resumable: re-asking for missing blobs and re-committing the same manifest is idempotent and converges on the same manifest digest.
Consequences
- v1alpha3 Form Definitions drop
artifactUrl,artifactSha256,artifactMediaType, and artifact-source attributes; revision Forms carry artifact references (bundleRef, module lists) resolved through the upload API. - The provider computes digests from local files (
content_fileauthoring attributes), performs the upload, and persists only manifest digests. - Decision 0002 remains the retained rule for the frozen v1alpha1/v1alpha2 lanes; published bytes and their verification are unchanged.
- Conformance gains digest-mismatch, missing-blob, resume, and manifest validation checks.
Rejected alternatives
- Keep credential-free URLs alongside uploads. Rejected because two ingestion paths double the security surface and keep the availability dependency this decision removes.
- Pre-signed host upload URLs outside the API. Rejected because the contract must stay portable across hosts; pre-signed transport is a host implementation detail behind the same API.
- OCI registry as the required transport. Rejected because it imports a full registry protocol for what one content-addressed manifest API covers; an OCI adapter can still implement this contract.