From be3ac01a594e067ad97ca7c8b6265f11272896ba Mon Sep 17 00:00:00 2001 From: Sirui Wang Date: Fri, 18 Sep 2026 14:42:50 -0700 Subject: [PATCH] fix(templates): do not mount the CodeArtifact secret while building project code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `Dockerfile-uv.j2` installs in two steps and mounted the broker secret on both. The second step runs `uv sync` after `COPY project`, which builds the agent's own project — and a PEP 517 backend is project-controlled code, either an in-tree module named by `backend-path` or whatever `[build-system] requires` pulls in. With the secret mounted there it can read the token, and the build has network. Reproduced before fixing. The vector needs only files the templates already copy — `pyproject.toml` declaring `backend-path = ["project"]`, plus one module under `project/` — so no Dockerfile change is required, which is exactly the threat PRIVATE_INDEX.md already says it defends against: a contributed change to a project file is far less conspicuous in review than a curl in a Dockerfile. What the backend captured: secret-file: index-url = https://aws:FAKE%2BTOKEN%2FVALUE%3D@.../simple/ env password: FAKE+TOKEN/VALUE= <- decoded, not just the encoded URL The second step no longer mounts it. Dependencies, private ones included, are already installed by the first step, so nothing is lost. Verified against a package published ONLY to a local private index and absent from public PyPI (pypi.org returns 404 for it), which is the sgp-obs case: | build succeeds | both steps: yes | step 1 only: yes | | private-index package installs | yes | YES | | backend reads the secret file | yes | | | backend reads the decoded token | yes | | `Dockerfile.j2`, the requirements.txt variant, never had this: it installs and only then copies the project, so no project-controlled code runs while the secret is mounted. Left alone. Raised by Greptile on #525. Fixing it here rather than there — #525 is the release-please branch, and a push to it would be overwritten by the next regeneration. Co-Authored-By: Claude Opus 5 --- .../lib/cli/templates/PRIVATE_INDEX.md | 32 +++++++++++++++++++ .../default-claude-code/Dockerfile-uv.j2 | 18 ++++++----- .../templates/default-codex/Dockerfile-uv.j2 | 18 ++++++----- .../default-langgraph/Dockerfile-uv.j2 | 18 ++++++----- .../default-openai-agents/Dockerfile-uv.j2 | 18 ++++++----- .../default-pydantic-ai/Dockerfile-uv.j2 | 18 ++++++----- .../cli/templates/default/Dockerfile-uv.j2 | 18 ++++++----- .../sync-claude-code/Dockerfile-uv.j2 | 18 ++++++----- .../cli/templates/sync-codex/Dockerfile-uv.j2 | 18 ++++++----- .../templates/sync-langgraph/Dockerfile-uv.j2 | 18 ++++++----- .../Dockerfile-uv.j2 | 18 ++++++----- .../sync-openai-agents/Dockerfile-uv.j2 | 18 ++++++----- .../sync-pydantic-ai/Dockerfile-uv.j2 | 18 ++++++----- .../lib/cli/templates/sync/Dockerfile-uv.j2 | 18 ++++++----- .../temporal-claude-code/Dockerfile-uv.j2 | 18 ++++++----- .../templates/temporal-codex/Dockerfile-uv.j2 | 18 ++++++----- .../temporal-langgraph/Dockerfile-uv.j2 | 18 ++++++----- .../temporal-openai-agents/Dockerfile-uv.j2 | 18 ++++++----- .../temporal-pydantic-ai/Dockerfile-uv.j2 | 18 ++++++----- .../cli/templates/temporal/Dockerfile-uv.j2 | 18 ++++++----- 20 files changed, 222 insertions(+), 152 deletions(-) diff --git a/src/agentex/lib/cli/templates/PRIVATE_INDEX.md b/src/agentex/lib/cli/templates/PRIVATE_INDEX.md index 932bd9819..2e845e44c 100644 --- a/src/agentex/lib/cli/templates/PRIVATE_INDEX.md +++ b/src/agentex/lib/cli/templates/PRIVATE_INDEX.md @@ -42,6 +42,38 @@ The name must be exactly `scale-pypi`. uv applies `UV_INDEX_SCALE_PYPI_USERNAME` silently stop applying. Setting `UV_INDEX_URL` instead does not authenticate a *named* index at all, and the resolve fails with a 401. +## The secret is scoped to the dependency step only + +`Dockerfile-uv.j2` installs in two steps, and only the first one mounts the broker secret: + +| Step | What it does | Secret | +| --- | --- | --- | +| `uv sync --no-install-project` | resolves and installs dependencies, private ones included | mounted | +| `uv sync` (after `COPY project`) | builds and installs the agent's own project | **not mounted** | + +The second step runs the agent's own PEP 517 build backend, and that is project-controlled +code — an in-tree `backend-path` module, or whatever `[build-system] requires` names. With the +secret mounted there it can read `/run/secrets/codeartifact-pip-conf` and the decoded +`UV_INDEX_SCALE_PYPI_PASSWORD`, and the build has network, so the CodeArtifact token can go +anywhere. That is the same threat this file already describes below — a contributed change to a +*project* file, far less conspicuous in review than a `curl` in the Dockerfile — and it needs +only files the templates already copy: `pyproject.toml` and something under `project/`. + +Reproduced against the previous layout, then re-run against this one: + +| | secret on both steps | secret on step 1 only | +| --- | --- | --- | +| build succeeds | yes | yes | +| package from the private index installs | yes | **yes** | +| build backend reads the secret file | **yes** | `` | +| build backend reads the decoded token | **yes** | `` | + +Nothing is lost by dropping it: dependencies are already installed by the first step, so the +second has nothing left to fetch from the mirror. + +`Dockerfile.j2` (the `requirements.txt` variant) never had this problem — it installs and only +then copies the project, so no project-controlled code runs while the secret is mounted. + ## Three things that are easy to get wrong **The token arrives percent-encoded.** The buildspec URL-encodes it to embed it in the pip config's diff --git a/src/agentex/lib/cli/templates/default-claude-code/Dockerfile-uv.j2 b/src/agentex/lib/cli/templates/default-claude-code/Dockerfile-uv.j2 index 8a22d0f89..055014ce4 100644 --- a/src/agentex/lib/cli/templates/default-claude-code/Dockerfile-uv.j2 +++ b/src/agentex/lib/cli/templates/default-claude-code/Dockerfile-uv.j2 @@ -53,15 +53,17 @@ RUN --mount=type=cache,target=/root/.cache/uv \ # Copy the project code COPY {{ project_path_from_build_root }}/project ./project -# Install the project +# Install the project. +# +# No broker secret on this step, deliberately. Unlike the step above, this one runs the +# agent's OWN build backend — and a PEP 517 backend is project-controlled code (an +# in-tree `backend-path` module, or whatever `[build-system] requires` names). With the +# secret mounted here it could read /run/secrets/codeartifact-pip-conf and the decoded +# UV_INDEX_SCALE_PYPI_PASSWORD and send the CodeArtifact token anywhere; the build has +# network. Reproduced before this change. Dependencies — including the private ones — +# are already installed by the step above, so nothing is lost by dropping it here. +# See PRIVATE_INDEX.md. RUN --mount=type=cache,target=/root/.cache/uv \ - --mount=type=secret,id=codeartifact-pip-conf,required=false \ - if [ -s /run/secrets/codeartifact-pip-conf ]; then \ - export UV_INDEX="scale-pypi=$(sed -n 's#.*index-url = https://aws:[^@]*@\(.*\)#https://\1#p' /run/secrets/codeartifact-pip-conf | head -1)"; \ - export UV_INDEX_SCALE_PYPI_USERNAME=aws; \ - export UV_INDEX_SCALE_PYPI_PASSWORD="$(sed -n 's#.*index-url = https://aws:\([^@]*\)@.*#\1#p' /run/secrets/codeartifact-pip-conf \ - | python3 -c 'import sys,urllib.parse;print(urllib.parse.unquote(sys.stdin.read().strip()))')"; \ - fi; \ uv sync --no-dev ENV PATH="/app/{{ project_path_from_build_root }}/.venv/bin:$PATH" diff --git a/src/agentex/lib/cli/templates/default-codex/Dockerfile-uv.j2 b/src/agentex/lib/cli/templates/default-codex/Dockerfile-uv.j2 index b3c03c988..750496ba9 100644 --- a/src/agentex/lib/cli/templates/default-codex/Dockerfile-uv.j2 +++ b/src/agentex/lib/cli/templates/default-codex/Dockerfile-uv.j2 @@ -53,15 +53,17 @@ RUN --mount=type=cache,target=/root/.cache/uv \ # Copy the project code COPY {{ project_path_from_build_root }}/project ./project -# Install the project +# Install the project. +# +# No broker secret on this step, deliberately. Unlike the step above, this one runs the +# agent's OWN build backend — and a PEP 517 backend is project-controlled code (an +# in-tree `backend-path` module, or whatever `[build-system] requires` names). With the +# secret mounted here it could read /run/secrets/codeartifact-pip-conf and the decoded +# UV_INDEX_SCALE_PYPI_PASSWORD and send the CodeArtifact token anywhere; the build has +# network. Reproduced before this change. Dependencies — including the private ones — +# are already installed by the step above, so nothing is lost by dropping it here. +# See PRIVATE_INDEX.md. RUN --mount=type=cache,target=/root/.cache/uv \ - --mount=type=secret,id=codeartifact-pip-conf,required=false \ - if [ -s /run/secrets/codeartifact-pip-conf ]; then \ - export UV_INDEX="scale-pypi=$(sed -n 's#.*index-url = https://aws:[^@]*@\(.*\)#https://\1#p' /run/secrets/codeartifact-pip-conf | head -1)"; \ - export UV_INDEX_SCALE_PYPI_USERNAME=aws; \ - export UV_INDEX_SCALE_PYPI_PASSWORD="$(sed -n 's#.*index-url = https://aws:\([^@]*\)@.*#\1#p' /run/secrets/codeartifact-pip-conf \ - | python3 -c 'import sys,urllib.parse;print(urllib.parse.unquote(sys.stdin.read().strip()))')"; \ - fi; \ uv sync --no-dev ENV PATH="/app/{{ project_path_from_build_root }}/.venv/bin:$PATH" diff --git a/src/agentex/lib/cli/templates/default-langgraph/Dockerfile-uv.j2 b/src/agentex/lib/cli/templates/default-langgraph/Dockerfile-uv.j2 index 9b4f8d25b..a7abf4fda 100644 --- a/src/agentex/lib/cli/templates/default-langgraph/Dockerfile-uv.j2 +++ b/src/agentex/lib/cli/templates/default-langgraph/Dockerfile-uv.j2 @@ -49,15 +49,17 @@ RUN --mount=type=cache,target=/root/.cache/uv \ # Copy the project code COPY {{ project_path_from_build_root }}/project ./project -# Install the project +# Install the project. +# +# No broker secret on this step, deliberately. Unlike the step above, this one runs the +# agent's OWN build backend — and a PEP 517 backend is project-controlled code (an +# in-tree `backend-path` module, or whatever `[build-system] requires` names). With the +# secret mounted here it could read /run/secrets/codeartifact-pip-conf and the decoded +# UV_INDEX_SCALE_PYPI_PASSWORD and send the CodeArtifact token anywhere; the build has +# network. Reproduced before this change. Dependencies — including the private ones — +# are already installed by the step above, so nothing is lost by dropping it here. +# See PRIVATE_INDEX.md. RUN --mount=type=cache,target=/root/.cache/uv \ - --mount=type=secret,id=codeartifact-pip-conf,required=false \ - if [ -s /run/secrets/codeartifact-pip-conf ]; then \ - export UV_INDEX="scale-pypi=$(sed -n 's#.*index-url = https://aws:[^@]*@\(.*\)#https://\1#p' /run/secrets/codeartifact-pip-conf | head -1)"; \ - export UV_INDEX_SCALE_PYPI_USERNAME=aws; \ - export UV_INDEX_SCALE_PYPI_PASSWORD="$(sed -n 's#.*index-url = https://aws:\([^@]*\)@.*#\1#p' /run/secrets/codeartifact-pip-conf \ - | python3 -c 'import sys,urllib.parse;print(urllib.parse.unquote(sys.stdin.read().strip()))')"; \ - fi; \ uv sync --no-dev ENV PATH="/app/{{ project_path_from_build_root }}/.venv/bin:$PATH" diff --git a/src/agentex/lib/cli/templates/default-openai-agents/Dockerfile-uv.j2 b/src/agentex/lib/cli/templates/default-openai-agents/Dockerfile-uv.j2 index 9b4f8d25b..a7abf4fda 100644 --- a/src/agentex/lib/cli/templates/default-openai-agents/Dockerfile-uv.j2 +++ b/src/agentex/lib/cli/templates/default-openai-agents/Dockerfile-uv.j2 @@ -49,15 +49,17 @@ RUN --mount=type=cache,target=/root/.cache/uv \ # Copy the project code COPY {{ project_path_from_build_root }}/project ./project -# Install the project +# Install the project. +# +# No broker secret on this step, deliberately. Unlike the step above, this one runs the +# agent's OWN build backend — and a PEP 517 backend is project-controlled code (an +# in-tree `backend-path` module, or whatever `[build-system] requires` names). With the +# secret mounted here it could read /run/secrets/codeartifact-pip-conf and the decoded +# UV_INDEX_SCALE_PYPI_PASSWORD and send the CodeArtifact token anywhere; the build has +# network. Reproduced before this change. Dependencies — including the private ones — +# are already installed by the step above, so nothing is lost by dropping it here. +# See PRIVATE_INDEX.md. RUN --mount=type=cache,target=/root/.cache/uv \ - --mount=type=secret,id=codeartifact-pip-conf,required=false \ - if [ -s /run/secrets/codeartifact-pip-conf ]; then \ - export UV_INDEX="scale-pypi=$(sed -n 's#.*index-url = https://aws:[^@]*@\(.*\)#https://\1#p' /run/secrets/codeartifact-pip-conf | head -1)"; \ - export UV_INDEX_SCALE_PYPI_USERNAME=aws; \ - export UV_INDEX_SCALE_PYPI_PASSWORD="$(sed -n 's#.*index-url = https://aws:\([^@]*\)@.*#\1#p' /run/secrets/codeartifact-pip-conf \ - | python3 -c 'import sys,urllib.parse;print(urllib.parse.unquote(sys.stdin.read().strip()))')"; \ - fi; \ uv sync --no-dev ENV PATH="/app/{{ project_path_from_build_root }}/.venv/bin:$PATH" diff --git a/src/agentex/lib/cli/templates/default-pydantic-ai/Dockerfile-uv.j2 b/src/agentex/lib/cli/templates/default-pydantic-ai/Dockerfile-uv.j2 index 9b4f8d25b..a7abf4fda 100644 --- a/src/agentex/lib/cli/templates/default-pydantic-ai/Dockerfile-uv.j2 +++ b/src/agentex/lib/cli/templates/default-pydantic-ai/Dockerfile-uv.j2 @@ -49,15 +49,17 @@ RUN --mount=type=cache,target=/root/.cache/uv \ # Copy the project code COPY {{ project_path_from_build_root }}/project ./project -# Install the project +# Install the project. +# +# No broker secret on this step, deliberately. Unlike the step above, this one runs the +# agent's OWN build backend — and a PEP 517 backend is project-controlled code (an +# in-tree `backend-path` module, or whatever `[build-system] requires` names). With the +# secret mounted here it could read /run/secrets/codeartifact-pip-conf and the decoded +# UV_INDEX_SCALE_PYPI_PASSWORD and send the CodeArtifact token anywhere; the build has +# network. Reproduced before this change. Dependencies — including the private ones — +# are already installed by the step above, so nothing is lost by dropping it here. +# See PRIVATE_INDEX.md. RUN --mount=type=cache,target=/root/.cache/uv \ - --mount=type=secret,id=codeartifact-pip-conf,required=false \ - if [ -s /run/secrets/codeartifact-pip-conf ]; then \ - export UV_INDEX="scale-pypi=$(sed -n 's#.*index-url = https://aws:[^@]*@\(.*\)#https://\1#p' /run/secrets/codeartifact-pip-conf | head -1)"; \ - export UV_INDEX_SCALE_PYPI_USERNAME=aws; \ - export UV_INDEX_SCALE_PYPI_PASSWORD="$(sed -n 's#.*index-url = https://aws:\([^@]*\)@.*#\1#p' /run/secrets/codeartifact-pip-conf \ - | python3 -c 'import sys,urllib.parse;print(urllib.parse.unquote(sys.stdin.read().strip()))')"; \ - fi; \ uv sync --no-dev ENV PATH="/app/{{ project_path_from_build_root }}/.venv/bin:$PATH" diff --git a/src/agentex/lib/cli/templates/default/Dockerfile-uv.j2 b/src/agentex/lib/cli/templates/default/Dockerfile-uv.j2 index 9b4f8d25b..a7abf4fda 100644 --- a/src/agentex/lib/cli/templates/default/Dockerfile-uv.j2 +++ b/src/agentex/lib/cli/templates/default/Dockerfile-uv.j2 @@ -49,15 +49,17 @@ RUN --mount=type=cache,target=/root/.cache/uv \ # Copy the project code COPY {{ project_path_from_build_root }}/project ./project -# Install the project +# Install the project. +# +# No broker secret on this step, deliberately. Unlike the step above, this one runs the +# agent's OWN build backend — and a PEP 517 backend is project-controlled code (an +# in-tree `backend-path` module, or whatever `[build-system] requires` names). With the +# secret mounted here it could read /run/secrets/codeartifact-pip-conf and the decoded +# UV_INDEX_SCALE_PYPI_PASSWORD and send the CodeArtifact token anywhere; the build has +# network. Reproduced before this change. Dependencies — including the private ones — +# are already installed by the step above, so nothing is lost by dropping it here. +# See PRIVATE_INDEX.md. RUN --mount=type=cache,target=/root/.cache/uv \ - --mount=type=secret,id=codeartifact-pip-conf,required=false \ - if [ -s /run/secrets/codeartifact-pip-conf ]; then \ - export UV_INDEX="scale-pypi=$(sed -n 's#.*index-url = https://aws:[^@]*@\(.*\)#https://\1#p' /run/secrets/codeartifact-pip-conf | head -1)"; \ - export UV_INDEX_SCALE_PYPI_USERNAME=aws; \ - export UV_INDEX_SCALE_PYPI_PASSWORD="$(sed -n 's#.*index-url = https://aws:\([^@]*\)@.*#\1#p' /run/secrets/codeartifact-pip-conf \ - | python3 -c 'import sys,urllib.parse;print(urllib.parse.unquote(sys.stdin.read().strip()))')"; \ - fi; \ uv sync --no-dev ENV PATH="/app/{{ project_path_from_build_root }}/.venv/bin:$PATH" diff --git a/src/agentex/lib/cli/templates/sync-claude-code/Dockerfile-uv.j2 b/src/agentex/lib/cli/templates/sync-claude-code/Dockerfile-uv.j2 index 8a22d0f89..055014ce4 100644 --- a/src/agentex/lib/cli/templates/sync-claude-code/Dockerfile-uv.j2 +++ b/src/agentex/lib/cli/templates/sync-claude-code/Dockerfile-uv.j2 @@ -53,15 +53,17 @@ RUN --mount=type=cache,target=/root/.cache/uv \ # Copy the project code COPY {{ project_path_from_build_root }}/project ./project -# Install the project +# Install the project. +# +# No broker secret on this step, deliberately. Unlike the step above, this one runs the +# agent's OWN build backend — and a PEP 517 backend is project-controlled code (an +# in-tree `backend-path` module, or whatever `[build-system] requires` names). With the +# secret mounted here it could read /run/secrets/codeartifact-pip-conf and the decoded +# UV_INDEX_SCALE_PYPI_PASSWORD and send the CodeArtifact token anywhere; the build has +# network. Reproduced before this change. Dependencies — including the private ones — +# are already installed by the step above, so nothing is lost by dropping it here. +# See PRIVATE_INDEX.md. RUN --mount=type=cache,target=/root/.cache/uv \ - --mount=type=secret,id=codeartifact-pip-conf,required=false \ - if [ -s /run/secrets/codeartifact-pip-conf ]; then \ - export UV_INDEX="scale-pypi=$(sed -n 's#.*index-url = https://aws:[^@]*@\(.*\)#https://\1#p' /run/secrets/codeartifact-pip-conf | head -1)"; \ - export UV_INDEX_SCALE_PYPI_USERNAME=aws; \ - export UV_INDEX_SCALE_PYPI_PASSWORD="$(sed -n 's#.*index-url = https://aws:\([^@]*\)@.*#\1#p' /run/secrets/codeartifact-pip-conf \ - | python3 -c 'import sys,urllib.parse;print(urllib.parse.unquote(sys.stdin.read().strip()))')"; \ - fi; \ uv sync --no-dev ENV PATH="/app/{{ project_path_from_build_root }}/.venv/bin:$PATH" diff --git a/src/agentex/lib/cli/templates/sync-codex/Dockerfile-uv.j2 b/src/agentex/lib/cli/templates/sync-codex/Dockerfile-uv.j2 index b3c03c988..750496ba9 100644 --- a/src/agentex/lib/cli/templates/sync-codex/Dockerfile-uv.j2 +++ b/src/agentex/lib/cli/templates/sync-codex/Dockerfile-uv.j2 @@ -53,15 +53,17 @@ RUN --mount=type=cache,target=/root/.cache/uv \ # Copy the project code COPY {{ project_path_from_build_root }}/project ./project -# Install the project +# Install the project. +# +# No broker secret on this step, deliberately. Unlike the step above, this one runs the +# agent's OWN build backend — and a PEP 517 backend is project-controlled code (an +# in-tree `backend-path` module, or whatever `[build-system] requires` names). With the +# secret mounted here it could read /run/secrets/codeartifact-pip-conf and the decoded +# UV_INDEX_SCALE_PYPI_PASSWORD and send the CodeArtifact token anywhere; the build has +# network. Reproduced before this change. Dependencies — including the private ones — +# are already installed by the step above, so nothing is lost by dropping it here. +# See PRIVATE_INDEX.md. RUN --mount=type=cache,target=/root/.cache/uv \ - --mount=type=secret,id=codeartifact-pip-conf,required=false \ - if [ -s /run/secrets/codeartifact-pip-conf ]; then \ - export UV_INDEX="scale-pypi=$(sed -n 's#.*index-url = https://aws:[^@]*@\(.*\)#https://\1#p' /run/secrets/codeartifact-pip-conf | head -1)"; \ - export UV_INDEX_SCALE_PYPI_USERNAME=aws; \ - export UV_INDEX_SCALE_PYPI_PASSWORD="$(sed -n 's#.*index-url = https://aws:\([^@]*\)@.*#\1#p' /run/secrets/codeartifact-pip-conf \ - | python3 -c 'import sys,urllib.parse;print(urllib.parse.unquote(sys.stdin.read().strip()))')"; \ - fi; \ uv sync --no-dev ENV PATH="/app/{{ project_path_from_build_root }}/.venv/bin:$PATH" diff --git a/src/agentex/lib/cli/templates/sync-langgraph/Dockerfile-uv.j2 b/src/agentex/lib/cli/templates/sync-langgraph/Dockerfile-uv.j2 index 9b4f8d25b..a7abf4fda 100644 --- a/src/agentex/lib/cli/templates/sync-langgraph/Dockerfile-uv.j2 +++ b/src/agentex/lib/cli/templates/sync-langgraph/Dockerfile-uv.j2 @@ -49,15 +49,17 @@ RUN --mount=type=cache,target=/root/.cache/uv \ # Copy the project code COPY {{ project_path_from_build_root }}/project ./project -# Install the project +# Install the project. +# +# No broker secret on this step, deliberately. Unlike the step above, this one runs the +# agent's OWN build backend — and a PEP 517 backend is project-controlled code (an +# in-tree `backend-path` module, or whatever `[build-system] requires` names). With the +# secret mounted here it could read /run/secrets/codeartifact-pip-conf and the decoded +# UV_INDEX_SCALE_PYPI_PASSWORD and send the CodeArtifact token anywhere; the build has +# network. Reproduced before this change. Dependencies — including the private ones — +# are already installed by the step above, so nothing is lost by dropping it here. +# See PRIVATE_INDEX.md. RUN --mount=type=cache,target=/root/.cache/uv \ - --mount=type=secret,id=codeartifact-pip-conf,required=false \ - if [ -s /run/secrets/codeartifact-pip-conf ]; then \ - export UV_INDEX="scale-pypi=$(sed -n 's#.*index-url = https://aws:[^@]*@\(.*\)#https://\1#p' /run/secrets/codeartifact-pip-conf | head -1)"; \ - export UV_INDEX_SCALE_PYPI_USERNAME=aws; \ - export UV_INDEX_SCALE_PYPI_PASSWORD="$(sed -n 's#.*index-url = https://aws:\([^@]*\)@.*#\1#p' /run/secrets/codeartifact-pip-conf \ - | python3 -c 'import sys,urllib.parse;print(urllib.parse.unquote(sys.stdin.read().strip()))')"; \ - fi; \ uv sync --no-dev ENV PATH="/app/{{ project_path_from_build_root }}/.venv/bin:$PATH" diff --git a/src/agentex/lib/cli/templates/sync-openai-agents-local-sandbox/Dockerfile-uv.j2 b/src/agentex/lib/cli/templates/sync-openai-agents-local-sandbox/Dockerfile-uv.j2 index 9b4f8d25b..a7abf4fda 100644 --- a/src/agentex/lib/cli/templates/sync-openai-agents-local-sandbox/Dockerfile-uv.j2 +++ b/src/agentex/lib/cli/templates/sync-openai-agents-local-sandbox/Dockerfile-uv.j2 @@ -49,15 +49,17 @@ RUN --mount=type=cache,target=/root/.cache/uv \ # Copy the project code COPY {{ project_path_from_build_root }}/project ./project -# Install the project +# Install the project. +# +# No broker secret on this step, deliberately. Unlike the step above, this one runs the +# agent's OWN build backend — and a PEP 517 backend is project-controlled code (an +# in-tree `backend-path` module, or whatever `[build-system] requires` names). With the +# secret mounted here it could read /run/secrets/codeartifact-pip-conf and the decoded +# UV_INDEX_SCALE_PYPI_PASSWORD and send the CodeArtifact token anywhere; the build has +# network. Reproduced before this change. Dependencies — including the private ones — +# are already installed by the step above, so nothing is lost by dropping it here. +# See PRIVATE_INDEX.md. RUN --mount=type=cache,target=/root/.cache/uv \ - --mount=type=secret,id=codeartifact-pip-conf,required=false \ - if [ -s /run/secrets/codeartifact-pip-conf ]; then \ - export UV_INDEX="scale-pypi=$(sed -n 's#.*index-url = https://aws:[^@]*@\(.*\)#https://\1#p' /run/secrets/codeartifact-pip-conf | head -1)"; \ - export UV_INDEX_SCALE_PYPI_USERNAME=aws; \ - export UV_INDEX_SCALE_PYPI_PASSWORD="$(sed -n 's#.*index-url = https://aws:\([^@]*\)@.*#\1#p' /run/secrets/codeartifact-pip-conf \ - | python3 -c 'import sys,urllib.parse;print(urllib.parse.unquote(sys.stdin.read().strip()))')"; \ - fi; \ uv sync --no-dev ENV PATH="/app/{{ project_path_from_build_root }}/.venv/bin:$PATH" diff --git a/src/agentex/lib/cli/templates/sync-openai-agents/Dockerfile-uv.j2 b/src/agentex/lib/cli/templates/sync-openai-agents/Dockerfile-uv.j2 index 9b4f8d25b..a7abf4fda 100644 --- a/src/agentex/lib/cli/templates/sync-openai-agents/Dockerfile-uv.j2 +++ b/src/agentex/lib/cli/templates/sync-openai-agents/Dockerfile-uv.j2 @@ -49,15 +49,17 @@ RUN --mount=type=cache,target=/root/.cache/uv \ # Copy the project code COPY {{ project_path_from_build_root }}/project ./project -# Install the project +# Install the project. +# +# No broker secret on this step, deliberately. Unlike the step above, this one runs the +# agent's OWN build backend — and a PEP 517 backend is project-controlled code (an +# in-tree `backend-path` module, or whatever `[build-system] requires` names). With the +# secret mounted here it could read /run/secrets/codeartifact-pip-conf and the decoded +# UV_INDEX_SCALE_PYPI_PASSWORD and send the CodeArtifact token anywhere; the build has +# network. Reproduced before this change. Dependencies — including the private ones — +# are already installed by the step above, so nothing is lost by dropping it here. +# See PRIVATE_INDEX.md. RUN --mount=type=cache,target=/root/.cache/uv \ - --mount=type=secret,id=codeartifact-pip-conf,required=false \ - if [ -s /run/secrets/codeartifact-pip-conf ]; then \ - export UV_INDEX="scale-pypi=$(sed -n 's#.*index-url = https://aws:[^@]*@\(.*\)#https://\1#p' /run/secrets/codeartifact-pip-conf | head -1)"; \ - export UV_INDEX_SCALE_PYPI_USERNAME=aws; \ - export UV_INDEX_SCALE_PYPI_PASSWORD="$(sed -n 's#.*index-url = https://aws:\([^@]*\)@.*#\1#p' /run/secrets/codeartifact-pip-conf \ - | python3 -c 'import sys,urllib.parse;print(urllib.parse.unquote(sys.stdin.read().strip()))')"; \ - fi; \ uv sync --no-dev ENV PATH="/app/{{ project_path_from_build_root }}/.venv/bin:$PATH" diff --git a/src/agentex/lib/cli/templates/sync-pydantic-ai/Dockerfile-uv.j2 b/src/agentex/lib/cli/templates/sync-pydantic-ai/Dockerfile-uv.j2 index 9b4f8d25b..a7abf4fda 100644 --- a/src/agentex/lib/cli/templates/sync-pydantic-ai/Dockerfile-uv.j2 +++ b/src/agentex/lib/cli/templates/sync-pydantic-ai/Dockerfile-uv.j2 @@ -49,15 +49,17 @@ RUN --mount=type=cache,target=/root/.cache/uv \ # Copy the project code COPY {{ project_path_from_build_root }}/project ./project -# Install the project +# Install the project. +# +# No broker secret on this step, deliberately. Unlike the step above, this one runs the +# agent's OWN build backend — and a PEP 517 backend is project-controlled code (an +# in-tree `backend-path` module, or whatever `[build-system] requires` names). With the +# secret mounted here it could read /run/secrets/codeartifact-pip-conf and the decoded +# UV_INDEX_SCALE_PYPI_PASSWORD and send the CodeArtifact token anywhere; the build has +# network. Reproduced before this change. Dependencies — including the private ones — +# are already installed by the step above, so nothing is lost by dropping it here. +# See PRIVATE_INDEX.md. RUN --mount=type=cache,target=/root/.cache/uv \ - --mount=type=secret,id=codeartifact-pip-conf,required=false \ - if [ -s /run/secrets/codeartifact-pip-conf ]; then \ - export UV_INDEX="scale-pypi=$(sed -n 's#.*index-url = https://aws:[^@]*@\(.*\)#https://\1#p' /run/secrets/codeartifact-pip-conf | head -1)"; \ - export UV_INDEX_SCALE_PYPI_USERNAME=aws; \ - export UV_INDEX_SCALE_PYPI_PASSWORD="$(sed -n 's#.*index-url = https://aws:\([^@]*\)@.*#\1#p' /run/secrets/codeartifact-pip-conf \ - | python3 -c 'import sys,urllib.parse;print(urllib.parse.unquote(sys.stdin.read().strip()))')"; \ - fi; \ uv sync --no-dev ENV PATH="/app/{{ project_path_from_build_root }}/.venv/bin:$PATH" diff --git a/src/agentex/lib/cli/templates/sync/Dockerfile-uv.j2 b/src/agentex/lib/cli/templates/sync/Dockerfile-uv.j2 index 9b4f8d25b..a7abf4fda 100644 --- a/src/agentex/lib/cli/templates/sync/Dockerfile-uv.j2 +++ b/src/agentex/lib/cli/templates/sync/Dockerfile-uv.j2 @@ -49,15 +49,17 @@ RUN --mount=type=cache,target=/root/.cache/uv \ # Copy the project code COPY {{ project_path_from_build_root }}/project ./project -# Install the project +# Install the project. +# +# No broker secret on this step, deliberately. Unlike the step above, this one runs the +# agent's OWN build backend — and a PEP 517 backend is project-controlled code (an +# in-tree `backend-path` module, or whatever `[build-system] requires` names). With the +# secret mounted here it could read /run/secrets/codeartifact-pip-conf and the decoded +# UV_INDEX_SCALE_PYPI_PASSWORD and send the CodeArtifact token anywhere; the build has +# network. Reproduced before this change. Dependencies — including the private ones — +# are already installed by the step above, so nothing is lost by dropping it here. +# See PRIVATE_INDEX.md. RUN --mount=type=cache,target=/root/.cache/uv \ - --mount=type=secret,id=codeartifact-pip-conf,required=false \ - if [ -s /run/secrets/codeartifact-pip-conf ]; then \ - export UV_INDEX="scale-pypi=$(sed -n 's#.*index-url = https://aws:[^@]*@\(.*\)#https://\1#p' /run/secrets/codeartifact-pip-conf | head -1)"; \ - export UV_INDEX_SCALE_PYPI_USERNAME=aws; \ - export UV_INDEX_SCALE_PYPI_PASSWORD="$(sed -n 's#.*index-url = https://aws:\([^@]*\)@.*#\1#p' /run/secrets/codeartifact-pip-conf \ - | python3 -c 'import sys,urllib.parse;print(urllib.parse.unquote(sys.stdin.read().strip()))')"; \ - fi; \ uv sync --no-dev ENV PATH="/app/{{ project_path_from_build_root }}/.venv/bin:$PATH" diff --git a/src/agentex/lib/cli/templates/temporal-claude-code/Dockerfile-uv.j2 b/src/agentex/lib/cli/templates/temporal-claude-code/Dockerfile-uv.j2 index 1665bceb1..5a581a12e 100644 --- a/src/agentex/lib/cli/templates/temporal-claude-code/Dockerfile-uv.j2 +++ b/src/agentex/lib/cli/templates/temporal-claude-code/Dockerfile-uv.j2 @@ -61,15 +61,17 @@ RUN --mount=type=cache,target=/root/.cache/uv \ # Copy the project code COPY {{ project_path_from_build_root }}/project ./project -# Install the project +# Install the project. +# +# No broker secret on this step, deliberately. Unlike the step above, this one runs the +# agent's OWN build backend — and a PEP 517 backend is project-controlled code (an +# in-tree `backend-path` module, or whatever `[build-system] requires` names). With the +# secret mounted here it could read /run/secrets/codeartifact-pip-conf and the decoded +# UV_INDEX_SCALE_PYPI_PASSWORD and send the CodeArtifact token anywhere; the build has +# network. Reproduced before this change. Dependencies — including the private ones — +# are already installed by the step above, so nothing is lost by dropping it here. +# See PRIVATE_INDEX.md. RUN --mount=type=cache,target=/root/.cache/uv \ - --mount=type=secret,id=codeartifact-pip-conf,required=false \ - if [ -s /run/secrets/codeartifact-pip-conf ]; then \ - export UV_INDEX="scale-pypi=$(sed -n 's#.*index-url = https://aws:[^@]*@\(.*\)#https://\1#p' /run/secrets/codeartifact-pip-conf | head -1)"; \ - export UV_INDEX_SCALE_PYPI_USERNAME=aws; \ - export UV_INDEX_SCALE_PYPI_PASSWORD="$(sed -n 's#.*index-url = https://aws:\([^@]*\)@.*#\1#p' /run/secrets/codeartifact-pip-conf \ - | python3 -c 'import sys,urllib.parse;print(urllib.parse.unquote(sys.stdin.read().strip()))')"; \ - fi; \ uv sync --no-dev ENV PATH="/app/{{ project_path_from_build_root }}/.venv/bin:$PATH" diff --git a/src/agentex/lib/cli/templates/temporal-codex/Dockerfile-uv.j2 b/src/agentex/lib/cli/templates/temporal-codex/Dockerfile-uv.j2 index 41d83e31c..66364ba57 100644 --- a/src/agentex/lib/cli/templates/temporal-codex/Dockerfile-uv.j2 +++ b/src/agentex/lib/cli/templates/temporal-codex/Dockerfile-uv.j2 @@ -61,15 +61,17 @@ RUN --mount=type=cache,target=/root/.cache/uv \ # Copy the project code COPY {{ project_path_from_build_root }}/project ./project -# Install the project +# Install the project. +# +# No broker secret on this step, deliberately. Unlike the step above, this one runs the +# agent's OWN build backend — and a PEP 517 backend is project-controlled code (an +# in-tree `backend-path` module, or whatever `[build-system] requires` names). With the +# secret mounted here it could read /run/secrets/codeartifact-pip-conf and the decoded +# UV_INDEX_SCALE_PYPI_PASSWORD and send the CodeArtifact token anywhere; the build has +# network. Reproduced before this change. Dependencies — including the private ones — +# are already installed by the step above, so nothing is lost by dropping it here. +# See PRIVATE_INDEX.md. RUN --mount=type=cache,target=/root/.cache/uv \ - --mount=type=secret,id=codeartifact-pip-conf,required=false \ - if [ -s /run/secrets/codeartifact-pip-conf ]; then \ - export UV_INDEX="scale-pypi=$(sed -n 's#.*index-url = https://aws:[^@]*@\(.*\)#https://\1#p' /run/secrets/codeartifact-pip-conf | head -1)"; \ - export UV_INDEX_SCALE_PYPI_USERNAME=aws; \ - export UV_INDEX_SCALE_PYPI_PASSWORD="$(sed -n 's#.*index-url = https://aws:\([^@]*\)@.*#\1#p' /run/secrets/codeartifact-pip-conf \ - | python3 -c 'import sys,urllib.parse;print(urllib.parse.unquote(sys.stdin.read().strip()))')"; \ - fi; \ uv sync --no-dev ENV PATH="/app/{{ project_path_from_build_root }}/.venv/bin:$PATH" diff --git a/src/agentex/lib/cli/templates/temporal-langgraph/Dockerfile-uv.j2 b/src/agentex/lib/cli/templates/temporal-langgraph/Dockerfile-uv.j2 index 56b4d949c..c908420ee 100644 --- a/src/agentex/lib/cli/templates/temporal-langgraph/Dockerfile-uv.j2 +++ b/src/agentex/lib/cli/templates/temporal-langgraph/Dockerfile-uv.j2 @@ -55,15 +55,17 @@ RUN --mount=type=cache,target=/root/.cache/uv \ # Copy the project code COPY {{ project_path_from_build_root }}/project ./project -# Install the project +# Install the project. +# +# No broker secret on this step, deliberately. Unlike the step above, this one runs the +# agent's OWN build backend — and a PEP 517 backend is project-controlled code (an +# in-tree `backend-path` module, or whatever `[build-system] requires` names). With the +# secret mounted here it could read /run/secrets/codeartifact-pip-conf and the decoded +# UV_INDEX_SCALE_PYPI_PASSWORD and send the CodeArtifact token anywhere; the build has +# network. Reproduced before this change. Dependencies — including the private ones — +# are already installed by the step above, so nothing is lost by dropping it here. +# See PRIVATE_INDEX.md. RUN --mount=type=cache,target=/root/.cache/uv \ - --mount=type=secret,id=codeartifact-pip-conf,required=false \ - if [ -s /run/secrets/codeartifact-pip-conf ]; then \ - export UV_INDEX="scale-pypi=$(sed -n 's#.*index-url = https://aws:[^@]*@\(.*\)#https://\1#p' /run/secrets/codeartifact-pip-conf | head -1)"; \ - export UV_INDEX_SCALE_PYPI_USERNAME=aws; \ - export UV_INDEX_SCALE_PYPI_PASSWORD="$(sed -n 's#.*index-url = https://aws:\([^@]*\)@.*#\1#p' /run/secrets/codeartifact-pip-conf \ - | python3 -c 'import sys,urllib.parse;print(urllib.parse.unquote(sys.stdin.read().strip()))')"; \ - fi; \ uv sync --no-dev ENV PATH="/app/{{ project_path_from_build_root }}/.venv/bin:$PATH" diff --git a/src/agentex/lib/cli/templates/temporal-openai-agents/Dockerfile-uv.j2 b/src/agentex/lib/cli/templates/temporal-openai-agents/Dockerfile-uv.j2 index a674d7d35..5068db663 100644 --- a/src/agentex/lib/cli/templates/temporal-openai-agents/Dockerfile-uv.j2 +++ b/src/agentex/lib/cli/templates/temporal-openai-agents/Dockerfile-uv.j2 @@ -55,15 +55,17 @@ RUN --mount=type=cache,target=/root/.cache/uv \ # Copy the project code COPY {{ project_path_from_build_root }}/project ./project -# Install the project +# Install the project. +# +# No broker secret on this step, deliberately. Unlike the step above, this one runs the +# agent's OWN build backend — and a PEP 517 backend is project-controlled code (an +# in-tree `backend-path` module, or whatever `[build-system] requires` names). With the +# secret mounted here it could read /run/secrets/codeartifact-pip-conf and the decoded +# UV_INDEX_SCALE_PYPI_PASSWORD and send the CodeArtifact token anywhere; the build has +# network. Reproduced before this change. Dependencies — including the private ones — +# are already installed by the step above, so nothing is lost by dropping it here. +# See PRIVATE_INDEX.md. RUN --mount=type=cache,target=/root/.cache/uv \ - --mount=type=secret,id=codeartifact-pip-conf,required=false \ - if [ -s /run/secrets/codeartifact-pip-conf ]; then \ - export UV_INDEX="scale-pypi=$(sed -n 's#.*index-url = https://aws:[^@]*@\(.*\)#https://\1#p' /run/secrets/codeartifact-pip-conf | head -1)"; \ - export UV_INDEX_SCALE_PYPI_USERNAME=aws; \ - export UV_INDEX_SCALE_PYPI_PASSWORD="$(sed -n 's#.*index-url = https://aws:\([^@]*\)@.*#\1#p' /run/secrets/codeartifact-pip-conf \ - | python3 -c 'import sys,urllib.parse;print(urllib.parse.unquote(sys.stdin.read().strip()))')"; \ - fi; \ uv sync --no-dev ENV PATH="/app/{{ project_path_from_build_root }}/.venv/bin:$PATH" diff --git a/src/agentex/lib/cli/templates/temporal-pydantic-ai/Dockerfile-uv.j2 b/src/agentex/lib/cli/templates/temporal-pydantic-ai/Dockerfile-uv.j2 index a674d7d35..5068db663 100644 --- a/src/agentex/lib/cli/templates/temporal-pydantic-ai/Dockerfile-uv.j2 +++ b/src/agentex/lib/cli/templates/temporal-pydantic-ai/Dockerfile-uv.j2 @@ -55,15 +55,17 @@ RUN --mount=type=cache,target=/root/.cache/uv \ # Copy the project code COPY {{ project_path_from_build_root }}/project ./project -# Install the project +# Install the project. +# +# No broker secret on this step, deliberately. Unlike the step above, this one runs the +# agent's OWN build backend — and a PEP 517 backend is project-controlled code (an +# in-tree `backend-path` module, or whatever `[build-system] requires` names). With the +# secret mounted here it could read /run/secrets/codeartifact-pip-conf and the decoded +# UV_INDEX_SCALE_PYPI_PASSWORD and send the CodeArtifact token anywhere; the build has +# network. Reproduced before this change. Dependencies — including the private ones — +# are already installed by the step above, so nothing is lost by dropping it here. +# See PRIVATE_INDEX.md. RUN --mount=type=cache,target=/root/.cache/uv \ - --mount=type=secret,id=codeartifact-pip-conf,required=false \ - if [ -s /run/secrets/codeartifact-pip-conf ]; then \ - export UV_INDEX="scale-pypi=$(sed -n 's#.*index-url = https://aws:[^@]*@\(.*\)#https://\1#p' /run/secrets/codeartifact-pip-conf | head -1)"; \ - export UV_INDEX_SCALE_PYPI_USERNAME=aws; \ - export UV_INDEX_SCALE_PYPI_PASSWORD="$(sed -n 's#.*index-url = https://aws:\([^@]*\)@.*#\1#p' /run/secrets/codeartifact-pip-conf \ - | python3 -c 'import sys,urllib.parse;print(urllib.parse.unquote(sys.stdin.read().strip()))')"; \ - fi; \ uv sync --no-dev ENV PATH="/app/{{ project_path_from_build_root }}/.venv/bin:$PATH" diff --git a/src/agentex/lib/cli/templates/temporal/Dockerfile-uv.j2 b/src/agentex/lib/cli/templates/temporal/Dockerfile-uv.j2 index a674d7d35..5068db663 100644 --- a/src/agentex/lib/cli/templates/temporal/Dockerfile-uv.j2 +++ b/src/agentex/lib/cli/templates/temporal/Dockerfile-uv.j2 @@ -55,15 +55,17 @@ RUN --mount=type=cache,target=/root/.cache/uv \ # Copy the project code COPY {{ project_path_from_build_root }}/project ./project -# Install the project +# Install the project. +# +# No broker secret on this step, deliberately. Unlike the step above, this one runs the +# agent's OWN build backend — and a PEP 517 backend is project-controlled code (an +# in-tree `backend-path` module, or whatever `[build-system] requires` names). With the +# secret mounted here it could read /run/secrets/codeartifact-pip-conf and the decoded +# UV_INDEX_SCALE_PYPI_PASSWORD and send the CodeArtifact token anywhere; the build has +# network. Reproduced before this change. Dependencies — including the private ones — +# are already installed by the step above, so nothing is lost by dropping it here. +# See PRIVATE_INDEX.md. RUN --mount=type=cache,target=/root/.cache/uv \ - --mount=type=secret,id=codeartifact-pip-conf,required=false \ - if [ -s /run/secrets/codeartifact-pip-conf ]; then \ - export UV_INDEX="scale-pypi=$(sed -n 's#.*index-url = https://aws:[^@]*@\(.*\)#https://\1#p' /run/secrets/codeartifact-pip-conf | head -1)"; \ - export UV_INDEX_SCALE_PYPI_USERNAME=aws; \ - export UV_INDEX_SCALE_PYPI_PASSWORD="$(sed -n 's#.*index-url = https://aws:\([^@]*\)@.*#\1#p' /run/secrets/codeartifact-pip-conf \ - | python3 -c 'import sys,urllib.parse;print(urllib.parse.unquote(sys.stdin.read().strip()))')"; \ - fi; \ uv sync --no-dev ENV PATH="/app/{{ project_path_from_build_root }}/.venv/bin:$PATH"