Repository navigation
Conversation
grandizzy
left a comment
There was a problem hiding this comment.
ty! left couple of comments, please check
ceada15 to
796c83d
Compare
grandizzy
left a comment
There was a problem hiding this comment.
looks good, left one comment, think was added for testing?
|
cyclops audit |
|
cc @grandizzy Cyclops audit event published. View workflow run Config: config: |
tempoxyz-bot
left a comment
There was a problem hiding this comment.
👁️ Cyclops Review
PR #1264 adds a reproducible-build and promotion contract for the production Docker image and canonical Linux x86_64 release artifact. The consolidated review found several actionable trust-boundary issues in the workflow/bake wiring; see inline comments.
Reviewer Callouts
- ⚡ Event-matrix coverage: Add regression coverage that expands Docker metadata/tag outputs for
push,schedule, branch dispatch, and tag dispatch, and asserts production aliases are emitted only by the trusted promotion path. - ⚡ Build-context determinism:
.github/workflows/docker.yml:496-505downloads.tempo-genesis/genesis.jsonfrom a mutable URL beforeDockerfile.reproducibleperformsCOPY . .; it is not known to affect the final binary today, but adding it to.dockerignorewould remove an unnecessary external input from the reproducible context. - ⚡ Shipped binary provenance: Confirm
tempo-zone --version, RPC client version, and P2P client string contain the resolved SHA rather than a vergen placeholder when.gitis excluded from the Docker context. - ⚡ Allocator/runtime asymmetry:
JEMALLOC_OVERRIDE=/usr/lib/x86_64-linux-gnu/libjemalloc.ameans the canonical Linux artifact links Debian's jemalloc instead of the vendored crate build used elsewhere; confirm this is intentional for runtime and observability expectations.
c17e204 to
67021dd
Compare
67021dd to
5ed989a
Compare
grandizzy
left a comment
There was a problem hiding this comment.
ty! left couple of comments, pls check
26c095d to
48a2f12
Compare
|
+1 |
There was a problem hiding this comment.
Approving on behalf of @grandizzy, who approved this pull request (head 3fbe460a79a5) with a +1 comment via Voight-Kampff.
GitHub branch protection considers pull request reviews, not +1 comments. Voight-Kampff is recording this approval on the reviewer's behalf so branch protection requirements are met.
👁️ Cyclops Security ReviewLast reviewed:
|
| publish-companion-images: | ||
| name: Publish companion Docker images | ||
| needs: build-and-push | ||
| if: >- | ||
| github.repository == 'tempoxyz/zones' && | ||
| github.event_name != 'pull_request' && github.event_name != 'merge_group' | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| packages: write | ||
| id-token: write |
There was a problem hiding this comment.
Low: Companion tags update despite failed release verification
The new publish-companion-images job promotes builder-supplied archives to public companion image tags without waiting for production-reproducible-verify or validating companion contents. A compromised candidate builder can supply altered images that remain published even if node verification fails and blocks tempo-zone promotion.
Adds manual independent prover EIF measurement verification using the shared workflow from tempoxyz/gh-actions#193. Production and verification share the reproducible-profile compiler, pinned runtime recipe and timestamp-normalizing EIF packaging helper. Production records the source, genesis checksum, binary checksum and toolchain digest needed to reproduce its PCRs. The next production build adopts this recipe and new measurements. The toolchain is resolved from main and cached by recipe hash. Dispatch cannot supply an arbitrary image. Verification requires a genesis checksum, rejects non-main or conflicting verification requests, and uploads both EIFs, PCRs and file hashes for comparison. Stacked on #1264. Dispatch `reproducible_eif_verify=true` from main after merging. Instructions are in `docs/REPRODUCIBLE_BUILDS.md`.
Co-authored-by: Derek Cofausper <256792747+decofe@users.noreply.github.com>
Co-authored-by: Derek Cofausper <256792747+decofe@users.noreply.github.com>
Adds manual independent prover EIF measurement verification using the shared workflow from tempoxyz/gh-actions#193. Production and verification share the reproducible-profile compiler, pinned runtime recipe and timestamp-normalizing EIF packaging helper. Production records the source, genesis checksum, binary checksum and toolchain digest needed to reproduce its PCRs. The next production build adopts this recipe and new measurements. The toolchain is resolved from main and cached by recipe hash. Dispatch cannot supply an arbitrary image. Verification requires a genesis checksum, rejects non-main or conflicting verification requests, and uploads both EIFs, PCRs and file hashes for comparison. Stacked on #1264. Dispatch `reproducible_eif_verify=true` from main after merging. Instructions are in `docs/REPRODUCIBLE_BUILDS.md`.
c858a1b to
a6d9e7b
Compare
| trap cleanup EXIT | ||
|
|
||
| docker load --input "$RUNNER_TEMP/candidate-images/tempo-zone.tar" | ||
| immutable_image=tempo-zone:candidate | ||
| container_id="$(docker create "$immutable_image")" | ||
| docker cp "$container_id:$BINARY_PATH" "$RUNNER_TEMP/tempo-zone" | ||
| image_sha256="$(sha256sum "$RUNNER_TEMP/tempo-zone" | awk '{print $1}')" | ||
| [[ "$image_sha256" =~ ^[0-9a-f]{64}$ ]] || { | ||
| failure="invalid image binary SHA-256" | ||
| echo "Invalid image binary SHA-256: $image_sha256" >&2 | ||
| exit 1 | ||
| } | ||
|
|
||
| image_runtime_config="$(docker image inspect "$immutable_image" --format '{{json .Config}}' | \ | ||
| jq -cS '{Entrypoint, Cmd, Env, WorkingDir, User, ExposedPorts, Volumes, Healthcheck, StopSignal}')" | ||
| image_runtime_config_sha256="$(printf '%s' "$image_runtime_config" | sha256sum | awk '{print $1}')" | ||
| docker cp "$container_id:/etc/ssl/certs/ca-certificates.crt" "$RUNNER_TEMP/ca-certificates.crt" | ||
| image_ca_bundle_sha256="$(sha256sum "$RUNNER_TEMP/ca-certificates.crt" | awk '{print $1}')" | ||
|
|
||
| [[ "$image_runtime_config_sha256" =~ ^[0-9a-f]{64}$ ]] || { | ||
| failure="invalid image runtime-config SHA-256" | ||
| echo "Invalid image runtime-config SHA-256: $image_runtime_config_sha256" >&2 | ||
| exit 1 | ||
| } | ||
| [[ "$image_ca_bundle_sha256" =~ ^[0-9a-f]{64}$ ]] || { | ||
| failure="invalid image CA-bundle SHA-256" | ||
| echo "Invalid image CA-bundle SHA-256: $image_ca_bundle_sha256" >&2 | ||
| exit 1 | ||
| } | ||
|
|
||
| if [[ "$image_sha256" == "$CLEAN_SHA256" && \ | ||
| "$image_runtime_config_sha256" == "$CLEAN_RUNTIME_CONFIG_SHA256" && \ | ||
| "$image_ca_bundle_sha256" == "$CLEAN_CA_BUNDLE_SHA256" ]]; then | ||
| comparison_result="success" | ||
| echo "Staged tempo-zone binary and runtime inputs match the clean rebuild" | ||
| else | ||
| failure="staged binary or runtime input does not match clean rebuild" | ||
| echo "::error::Staged production reproducibility verification mismatch" | ||
| exit 1 | ||
| fi | ||
|
|
||
| # Registry write access exists only on this fresh verification runner. | ||
| # No candidate executable or build script runs here. | ||
| tagged_image="$IMAGE_REPOSITORY:$IMAGE_TAG" | ||
| docker tag "$immutable_image" "$tagged_image" | ||
| docker push "$tagged_image" |
There was a problem hiding this comment.
Medium: Unverified runtime files pass image promotion
The production verification gate compares the candidate image’s binary, selected configuration, and CA bundle, but not its remaining filesystem. A compromised candidate builder can supply an image with an unchanged binary and a modified runtime loader or preload file; the gate then promotes that image to production tags.
| target "tempo-zone" { | ||
| inherits = ["_common", "docker-metadata"] | ||
| target = "tempo-zone" | ||
| inherits = ["docker-metadata"] | ||
| dockerfile = "docker/Dockerfile.reproducible" | ||
| context = "." | ||
| target = "tempo-zone-reproducible" | ||
| args = { | ||
| SOURCE_DATE_EPOCH = "${SOURCE_DATE_EPOCH}" | ||
| GIT_SHA = "${GIT_SHA}" | ||
| VERSION = "${VERSION}" | ||
| } | ||
| labels = { | ||
| "org.opencontainers.image.description" = "Production tempo-zone image; verification covers the tempo-zone binary, runtime execution config, and CA bundle." | ||
| "org.tempoxyz.reproducible.verification-scope" = "tempo-zone-binary-runtime-config-ca-bundle" | ||
| } | ||
| platforms = ["linux/amd64"] | ||
| } |
There was a problem hiding this comment.
Needs review · unverified: Production image freezes its system CA trust store
Switching the production tempo-zone target to Dockerfile.reproducible makes its runtime install ca-certificates from a fixed May 1, 2026 Debian snapshot instead of the former runtime's updated apt sources. Scheduled clean rebuilds reproduce that same trust store; matching its hash does not establish that the roots remain current. Conditional impact: if an operator uses an HTTPS L1_HTTP_RPC_URL without replacing the image's…
Full finding
Switching the production tempo-zone target to Dockerfile.reproducible makes its runtime install ca-certificates from a fixed May 1, 2026 Debian snapshot instead of the former runtime's updated apt sources. Scheduled clean rebuilds reproduce that same trust store; matching its hash does not establish that the roots remain current. Conditional impact: if an operator uses an HTTPS L1_HTTP_RPC_URL without replacing the image's CA store, and a root trusted by the snapshot is subsequently distrusted, an interceptor able to present a certificate under that root can impersonate the RPC endpoint. L1 storage cache misses use its responses in EVM state reads. The review did not establish that a relevant root has in fact been removed or that a deployment uses this optional HTTPS path. Keep the binary build reproducible while refreshing and independently validating the runtime trust store, or require periodic signed snapshot updates.
First reported at 1894e63; recheck at this head: still present.
| workflow_dispatch: | ||
| inputs: | ||
| tag: | ||
| description: "Tag to release (e.g., v0.1.0)" | ||
| description: "Existing Git tag to release (e.g., v0.1.0)" | ||
| required: true | ||
| type: string |
There was a problem hiding this comment.
Needs review · unverified: Manual release can execute code from an unchecked tag on OIDC-enabled runners
A workflow_dispatch run on main can supply any existing syntactically valid tag, including one outside the v*.*.* push pattern. resolve-release checks that the tag resolves consistently, not that its commit is approved or descended from protected main. Both build jobs then check out that commit and execute its scripts/reproducible-build.sh with id-token: write. Setting dry_run=true skips the version check but does…
Full finding
A workflow_dispatch run on main can supply any existing syntactically valid tag, including one outside the v*.*.* push pattern. resolve-release checks that the tag resolves consistently, not that its commit is approved or descended from protected main. Both build jobs then check out that commit and execute its scripts/reproducible-build.sh with id-token: write. Setting dry_run=true skips the version check but does not skip either execution. If an actor can create such a tag and dispatch the workflow, tag-controlled shell code runs in the privileged workflow context; access to external credentials depends on the deployed OIDC trust policy. This manual-dispatch source change is absent from the previous build checkout. Require an approved tag or protected-main ancestry before executing checked-out scripts, and avoid granting OIDC permission to jobs that run untrusted tag contents.
First reported at 1894e63; recheck at this head: still present.
Compare the full exported runtime filesystem with a clean rebuild, delay companion tags until node verification succeeds, and require release tags to come from main before OIDC-enabled build jobs execute their contents.
Builds Linux x86_64 node images and release binaries with the canonical reproducible profile. Production publication builds the same
tempo-zoneimage target on Depot and an independent clean GitHub runner, compares their complete image IDs, and stages Depot's candidate only when they match. Companion image tags publish after this check succeeds. A verification-only dispatch exercises the comparison without publishing production tags.Docker candidate builds have read-only registry access and export archives by artifact ID. Release publication verifies the archived binary against a separate clean rebuild and revalidates its tag. Release tags must point to commits already on main before OIDC-enabled build jobs execute tagged code. Manual SHA and nightly image tags use the verified promotion path.