ci: build base template via e2b CLI in addition to DockerHub push#1401
ci: build base template via e2b CLI in addition to DockerHub push#1401mishushakov wants to merge 6 commits into
Conversation
Add a buildTemplate job that installs @e2b/cli from npm and runs `e2b template create base --memory-mb 512`, alongside the existing DockerHub image build. Drop the now-unused e2b.toml config. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
PR SummaryMedium Risk Overview The new CI step does not pass Reviewed by Cursor Bugbot for commit fbe6304. Bugbot is set up for automated code reviews on this repo. Configure here. |
Package ArtifactsBuilt from 248d6c5. Download artifacts from this workflow run. JS SDK ( npm install ./e2b-2.28.3-mishushakov-saskatoon-v1.0.tgzCLI ( npm install ./e2b-cli-2.11.1-mishushakov-saskatoon-v1.0.tgzPython SDK ( pip install ./e2b-2.27.1+mishushakov.saskatoon.v1-py3-none-any.whl |
|
|
||
| RUN groupadd --gid 1000 node \ | ||
| && useradd --uid 1000 --gid node --shell /bin/bash --create-home node | ||
| RUN groupadd -r node && useradd -r -g node -s /bin/bash -m node |
There was a problem hiding this comment.
🔴 The Dockerfile change from useradd --uid 1000 --gid 1000 to useradd -r (system account) is unrelated to this PR's CI scope and silently changes the runtime ABI of the published base template: node no longer has a stable, predictable UID/GID 1000 but instead gets a system UID allocated from /etc/login.defs's SYS_UID range (typically <1000), determined non-deterministically by whichever system accounts already exist in python:3.11.6. The line above still cites nodejs/docker-node as inspiration — that upstream pins UID 1000 by deliberate convention. Please either revert this change or restore explicit --uid 1000 --gid 1000 to preserve the contract for downstream consumers.
Extended reasoning...
What changes
-RUN groupadd --gid 1000 node \
- && useradd --uid 1000 --gid node --shell /bin/bash --create-home node
+RUN groupadd -r node && useradd -r -g node -s /bin/bash -m nodeThe -r flag on useradd/groupadd requests a system account, which allocates a UID/GID from the system range bounded by SYS_UID_MIN/SYS_UID_MAX in /etc/login.defs (100–999 in Debian bookworm, the base of python:3.11.6). The previous code explicitly pinned the node user and group to UID/GID 1000.
Why this is a behavior change for the published template
This Dockerfile produces the base sandbox template that downstream users consume via Sandbox.create('base') and that template authors extend with their own Dockerfiles. The numeric identity of the node user is part of that template's surface area:
- The comment immediately above this line (
# Inspired by https://github.com/nodejs/docker-node/blob/main/20/bookworm/Dockerfile) cites the canonicalnodejs/docker-nodeDockerfile, which deliberately pinsnodeto UID 1000 to match the host-user convention. After this change, the cited convention no longer holds, and the comment is stale. - The new UID is non-deterministic: it depends on which system users already exist in
python:3.11.6plus any system accounts created by the apt installs above (build-essential,util-linux,gh, …). A future bump of the python base image — or even a new transitive system user in any of those packages — can shift thenodeUID without any change to this Dockerfile. - Downstream impact in derived images and at runtime:
COPY --chown=node:node(name-resolved) andCOPY --chown=1000:1000(numeric) now refer to different identities.- Bind-mounted host directories owned by UID 1000 — the host-user convention the previous code participated in — are no longer owned by
nodeinside the sandbox. - Artifact consumers parsing UID/GID numerically see a different owner.
Step-by-step proof
Build the previous Dockerfile, then build the new one, in two scratch containers based on python:3.11.6:
# Old behavior
$ docker run --rm python:3.11.6 sh -c 'groupadd --gid 1000 node && useradd --uid 1000 --gid node --shell /bin/bash --create-home node && id node'
uid=1000(node) gid=1000(node) groups=1000(node)
# New behavior
$ docker run --rm python:3.11.6 sh -c 'groupadd -r node && useradd -r -g node -s /bin/bash -m node && id node'
uid=100(node) gid=101(node) groups=101(node)
The exact numeric UID/GID assigned in the second case is determined by useradd walking the system range looking for the first free slot — so the value drifts whenever the upstream image's system-user layout changes.
Addressing the refutation
A previous refutation argued that nothing in this repo currently does USER node or chown 1000, so the change is invisible. That reasoning is too narrow:
- The
basetemplate is published (per the existing DockerHub push + the newe2b template create basestep added in this same PR). Its consumers are not limited to this repository. They are arbitrary user-authoredFROM baseDockerfiles andSandbox.create('base')clients with bind-mounts. We cannot grep our own repo to assert no one depends on UID 1000. - The
nodejs/docker-nodeDockerfile likewise does not setUSER node— that's exactly why it pins UID 1000: so downstream authors who do opt intoUSER nodeor numeric chowns get a stable identity. Removing the pin defeats that contract for our derived template too. - Even within this repo, the loss of a stable UID is a regression in determinism that's worth preserving regardless of current internal callers — system UID allocation is order-dependent and image-version dependent.
How to fix
Either:
- Revert this hunk and leave the user-creation as it was (the cleanest option, since the PR's stated purpose is the CI changes), or
- Keep the modernized flags but restore the pin:
useradd --system --uid 1000 --gid node --shell /bin/bash --create-home node(and a matchinggroupadd --system --gid 1000 node).
If the intent is truly to switch to a system account, that should be its own PR with a changeset and a note that the published base template's UID has changed.
There was a problem hiding this comment.
user with uid 1000 and gid 1000 already exists
Build the CLI locally from the repo rather than installing the published @e2b/cli package, so the template build runs trusted code. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
0273ef7 to
ee86f02
Compare
Move the build-from-source + global install of the e2b CLI into a reusable composite action at .github/actions/build-cli so it can be shared across workflows. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
| - name: Parse .tool-versions | ||
| uses: wistia/parse-tool-versions@v2.1.1 | ||
| with: | ||
| filename: '.tool-versions' |
There was a problem hiding this comment.
🔒 Agentic Security Review
Severity: HIGH
This workflow executes wistia/parse-tool-versions@v2.1.1 by mutable tag inside a job that later uses E2B publishing credentials. Tag retarget or upstream compromise would allow attacker-controlled code to run in CI and steal those credentials.
Impact: A supply-chain compromise of the action can lead to unauthorized template publication/API usage via exfiltrated secrets.
Reviewed by Cursor Security Reviewer for commit 7f29aeb. Configure here.
|
|
||
| - name: Build and publish base template | ||
| working-directory: ./templates/base | ||
| run: e2b template create base --memory-mb 512 |
There was a problem hiding this comment.
🔒 Agentic Security Review
Severity: HIGH
E2B_API_KEY and E2B_ACCESS_TOKEN are defined at job scope, so every step in buildTemplate (including checkout and CLI build/install steps) receives publishing credentials. This broadens the blast radius of any compromised action/dependency script before publish executes.
Impact: CI supply-chain compromise in an earlier step can exfiltrate template-publishing credentials and enable unauthorized template publication/API actions.
Reviewed by Cursor Security Reviewer for commit 7f29aeb. Configure here.
The CLI no longer gates `template create` on an access token, so the E2B_API_KEY is sufficient. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit d7a7776. Configure here.
link-workspace-packages is disabled, so the CLI resolves its `e2b` dependency from the published registry package (which ships a prebuilt dist) rather than the workspace source. Building packages/js-sdk first had no effect on the CLI build. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>


Adds a
buildTemplateCI job that builds and publishes thebasetemplate through the e2b CLI, running alongside the existing DockerHub image push (renamed tobuildAndPushImage). For security, the CLI is built from source in this repo rather than installing the published@e2b/clipackage; this build-and-global-install logic lives in a reusable composite action at.github/actions/build-cliso it can be shared across workflows. Removes the statictemplates/base/e2b.tomlsince template config is now driven by the CLI invocation, and switches the Dockerfile'snodeuser/group creation to system accounts (-r).Usage
Any workflow can build and install the CLI globally with a single step:
🤖 Generated with Claude Code