Conversation
Add a second container image for Cursor's Agent CLI alongside the existing Claude Code CLI image. The build workflow now uses a matrix strategy to build both images in parallel, and the Makefile supports individual (build-claude, build-cursor) or combined (build) targets. The Cursor image is published as ghcr.io/opendatahub-io/ai-helpers-cursor and shares the same base tooling (Fedora, Node.js, Python, uv, gcloud, oc) as the Claude image. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Emilien Macchi <emacchi@redhat.com>
📝 WalkthroughWalkthroughThe pull request expands container image support from a single Claude image to multiple images (Claude and Cursor) across the build pipeline. The GitHub Actions workflow is updated to use a matrix strategy for building different container images with distinct Containerfiles and naming conventions. The Makefile is restructured to define per-image build variables and targets. A new Containerfile for the Cursor image is added, which installs development tools, Google Cloud CLI, OpenShift client, and configures a non-root user. Documentation is added to explain container execution patterns for the Cursor Agent CLI. Estimated code review effort🎯 3 (Moderate) | ⏱️ ~28 minutes 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 📝 Coding Plan for PR comments
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
|
||
| RUN echo '[google-cloud-cli]' > /etc/yum.repos.d/google-cloud-sdk.repo && \ | ||
| echo 'name=Google Cloud CLI' >> /etc/yum.repos.d/google-cloud-sdk.repo && \ | ||
| echo 'baseurl=https://packages.cloud.google.com/yum/repos/cloud-sdk-el10-$basearch' >> /etc/yum.repos.d/google-cloud-sdk.repo && \ |
There was a problem hiding this comment.
I think they only support x86_64: https://docs.cloud.google.com/sdk/docs/install-sdk#rpm so the $basearch is not needed here.
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.github/workflows/build.yml (1)
38-46:⚠️ Potential issue | 🟠 MajorPin all GitHub Actions to full commit SHAs (CWE-494).
Lines 38-46 and 52-64 use mutable tags (
@v6,@v4,@v7) instead of commit SHAs. If upstream tags are retargeted or compromised, the workflow executes attacker-controlled code.Replace each action with its full commit SHA:
actions/checkout@v6→actions/checkout@<sha>(v6)docker/setup-buildx-action@v4→docker/setup-buildx-action@<sha>(v4)docker/login-action@v4→docker/login-action@<sha>(v4)docker/metadata-action@v6→docker/metadata-action@<sha>(v6)docker/build-push-action@v7→docker/build-push-action@<sha>(v7)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/build.yml around lines 38 - 46, Replace mutable GitHub Actions tags with their immutable commit SHAs for each action usage to mitigate supply-chain risk: update actions/checkout@v6, docker/setup-buildx-action@v4, docker/login-action@v4, docker/metadata-action@v6, and docker/build-push-action@v7 to the exact commit SHA for the corresponding release; locate the usages of these action identifiers in the workflow and substitute the tag (e.g., `@v6/`@v4/@v7) with the full commit SHA retrieved from the action's GitHub releases or commit history, ensuring every occurrence is updated.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/build.yml:
- Around line 6-10: The pull_request workflow's 'paths' filter only watches
'images/**' and '.github/workflows/build.yml', which misses changes copied into
the image because both Containerfiles use 'context: .' and copy the repo into
'/opt/ai-helpers' (see images/cursor/Containerfile and
images/claude/Containerfile); update the workflow by removing the 'paths' filter
entirely or expanding it to include all files used in the build context (e.g.,
add '**' or explicit entries like 'helpers/**', 'scripts/**', 'Makefile',
'categories.yaml') so that changes affecting the image trigger the workflow.
In `@images/cursor/Containerfile`:
- Around line 32-33: The Dockerfile currently pipes remote installer scripts
straight into sh (the RUN curl -LsSf ... | ... sh invocation for the uv/astral
installer using UV_INSTALL_DIR and INSTALLER_NO_MODIFY_PATH), which risks
executing tampered code; change this to fetch a versioned release artifact,
verify its integrity (SHA256 or GPG) before execution, and only then run it:
download the installer to a file (pin a specific versioned URL), fetch or embed
the expected checksum or signature, validate the file with shasum/gpg, and
finally run the verified file (or prefer installing from a packaged release or
distro package) so the build fails if verification does not match.
- Around line 35-36: The Containerfile currently hardcodes the amd64 OpenShift
client archive in the RUN curl ... oc download line, which breaks arm64
multi-arch images; add a build ARG TARGETARCH at the top of the Containerfile
and use it to choose the correct archive name when downloading the oc binary
(e.g., map TARGETARCH to the archive suffix such that TARGETARCH=arm64 selects
openshift-client-linux-arm64.tar.gz and otherwise selects
openshift-client-linux.tar.gz), and then update the RUN curl ...
/usr/local/bin/oc command to reference that computed archive variable so
multi-arch builds pull the correct binary.
In `@Makefile`:
- Around line 65-71: Quote shell variables used in the image reference to
prevent word-splitting: update the Claude and Cursor build targets (the echo
lines and the build commands that use $(CONTAINER_RUNTIME),
$(CLAUDE_IMAGE_NAME), $(CURSOR_IMAGE_NAME), and $(IMAGE_TAG)) so the image tags
are quoted, e.g. use "$(CLAUDE_IMAGE_NAME):$(IMAGE_TAG)" and
"$(CURSOR_IMAGE_NAME):$(IMAGE_TAG)" in the -t arguments and in the echo
messages; keep $(CONTAINER_RUNTIME) invocation intact but ensure the image
references are wrapped in double quotes to avoid splitting.
In `@README.md`:
- Around line 215-224: The examples in README.md inline the actual
CURSOR_API_KEY value into the podman run command which leaks secrets via process
args; change both examples (the podman run snippets around the shown block and
the later one at 233-241) to avoid embedding the secret by passing only the
variable name (e.g., use -e CURSOR_API_KEY or --env CURSOR_API_KEY without
"=your-api-key"), or show using an env file (--env-file .env) or prompting to
export CURSOR_API_KEY in the shell beforehand, so the command no longer contains
the secret literal.
---
Outside diff comments:
In @.github/workflows/build.yml:
- Around line 38-46: Replace mutable GitHub Actions tags with their immutable
commit SHAs for each action usage to mitigate supply-chain risk: update
actions/checkout@v6, docker/setup-buildx-action@v4, docker/login-action@v4,
docker/metadata-action@v6, and docker/build-push-action@v7 to the exact commit
SHA for the corresponding release; locate the usages of these action identifiers
in the workflow and substitute the tag (e.g., `@v6/`@v4/@v7) with the full commit
SHA retrieved from the action's GitHub releases or commit history, ensuring
every occurrence is updated.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Central YAML (inherited), Organization UI (inherited)
Review profile: CHILL
Plan: Pro
Run ID: 83b79900-1b1e-44a9-ade2-120de783024d
📒 Files selected for processing (4)
.github/workflows/build.ymlMakefileREADME.mdimages/cursor/Containerfile
| pull_request: | ||
| branches: [ main ] | ||
| paths: | ||
| - 'images/claude/**' | ||
| - 'images/**' | ||
| - '.github/workflows/build.yml' |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, check if the workflow file exists and read the pull_request trigger section
cat -n .github/workflows/build.yml | head -30Repository: opendatahub-io/ai-helpers
Length of output: 780
🏁 Script executed:
# Check the Containerfiles mentioned
ls -la images/*/ContainerfileRepository: opendatahub-io/ai-helpers
Length of output: 222
🏁 Script executed:
# Read the Containerfiles to verify context and COPY statements
echo "=== images/cursor/Containerfile ===" && wc -l images/cursor/Containerfile
echo "=== images/claude/Containerfile ===" && wc -l images/claude/ContainerfileRepository: opendatahub-io/ai-helpers
Length of output: 202
🏁 Script executed:
# Read around lines 50-52 for both Containerfiles
echo "=== images/cursor/Containerfile lines 45-55 ===" && sed -n '45,55p' images/cursor/Containerfile
echo "=== images/claude/Containerfile lines 45-55 ===" && sed -n '45,55p' images/claude/ContainerfileRepository: opendatahub-io/ai-helpers
Length of output: 770
🏁 Script executed:
# Check what files exist in the root and subdirectories that might be in build context
git ls-files | head -50Repository: opendatahub-io/ai-helpers
Length of output: 1421
🏁 Script executed:
# Check for scripts directory and other files at root that could be copied
ls -la | grep -E '^d|^-' | head -20Repository: opendatahub-io/ai-helpers
Length of output: 1323
🏁 Script executed:
# Check if there's a scripts directory with files
find . -maxdepth 2 -type f -name "Makefile" -o -path "*/scripts/*" 2>/dev/null | head -20Repository: opendatahub-io/ai-helpers
Length of output: 192
🏁 Script executed:
# Verify the build context in the workflow - check if there's a docker build step that specifies context
cat -n .github/workflows/build.yml | grep -A 20 "docker build\|context:"Repository: opendatahub-io/ai-helpers
Length of output: 371
Major: the PR trigger skips files that are copied into the image.
Both Containerfiles build with context: . (line 66) and copy the entire repository into /opt/ai-helpers (line 51 in both images/cursor/Containerfile and images/claude/Containerfile), so a PR that only changes helpers/**, scripts/**, Makefile, categories.yaml, or other files at repository root can modify the image contents while this workflow never runs. The path filter at lines 8-10 only covers images/** and .github/workflows/build.yml. Remove the paths filter or expand it to include all files in the build context.
Remediation
pull_request:
branches: [ main ]
- paths:
- - 'images/**'
- - '.github/workflows/build.yml'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/build.yml around lines 6 - 10, The pull_request workflow's
'paths' filter only watches 'images/**' and '.github/workflows/build.yml', which
misses changes copied into the image because both Containerfiles use 'context:
.' and copy the repo into '/opt/ai-helpers' (see images/cursor/Containerfile and
images/claude/Containerfile); update the workflow by removing the 'paths' filter
entirely or expanding it to include all files used in the build context (e.g.,
add '**' or explicit entries like 'helpers/**', 'scripts/**', 'Makefile',
'categories.yaml') so that changes affecting the image trigger the workflow.
| RUN curl -LsSf https://astral.sh/uv/install.sh | UV_INSTALL_DIR="/usr/local/bin/" INSTALLER_NO_MODIFY_PATH=1 sh | ||
|
|
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n images/cursor/Containerfile | sed -n '25,65p'Repository: opendatahub-io/ai-helpers
Length of output: 1850
Critical: uv and Cursor installers execute remote scripts without integrity verification (CWE-829).
Lines 32 and 58 both pipe unverified remote scripts directly to shell interpreters, allowing arbitrary code execution from upstream sources or CDN compromise during build. Version the installer URLs and verify checksums before execution.
Remediation
# Install uv for PEP 723 script dependency management
-RUN curl -LsSf https://astral.sh/uv/install.sh | UV_INSTALL_DIR="/usr/local/bin/" INSTALLER_NO_MODIFY_PATH=1 sh
+ARG UV_INSTALL_URL=<versioned-url>
+ARG UV_INSTALL_SHA256=<published-sha256>
+RUN curl -fsSLo /tmp/uv-install.sh "${UV_INSTALL_URL}" \
+ && echo "${UV_INSTALL_SHA256} /tmp/uv-install.sh" | sha256sum -c - \
+ && UV_INSTALL_DIR="/usr/local/bin/" INSTALLER_NO_MODIFY_PATH=1 sh /tmp/uv-install.sh \
+ && rm -f /tmp/uv-install.sh
# Install Cursor CLI
-RUN curl -fsSL https://cursor.com/install | bash
+ARG CURSOR_INSTALL_URL=<versioned-url>
+ARG CURSOR_INSTALL_SHA256=<published-sha256>
+RUN curl -fsSLo /tmp/cursor-install.sh "${CURSOR_INSTALL_URL}" \
+ && echo "${CURSOR_INSTALL_SHA256} /tmp/cursor-install.sh" | sha256sum -c - \
+ && bash /tmp/cursor-install.sh \
+ && rm -f /tmp/cursor-install.sh🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@images/cursor/Containerfile` around lines 32 - 33, The Dockerfile currently
pipes remote installer scripts straight into sh (the RUN curl -LsSf ... | ... sh
invocation for the uv/astral installer using UV_INSTALL_DIR and
INSTALLER_NO_MODIFY_PATH), which risks executing tampered code; change this to
fetch a versioned release artifact, verify its integrity (SHA256 or GPG) before
execution, and only then run it: download the installer to a file (pin a
specific versioned URL), fetch or embed the expected checksum or signature,
validate the file with shasum/gpg, and finally run the verified file (or prefer
installing from a packaged release or distro package) so the build fails if
verification does not match.
| RUN curl -LsSf https://mirror.openshift.com/pub/openshift-v4/clients/ocp/stable/openshift-client-linux.tar.gz | tar xzf - -C /usr/local/bin/ oc \ | ||
| && chmod +x /usr/local/bin/oc |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find . -name "Containerfile" -type fRepository: opendatahub-io/ai-helpers
Length of output: 128
🏁 Script executed:
find . -type f -name "*docker*" -o -name "*compose*" -o -name "*.yml" -o -name "*.yaml" | grep -E "(workflow|action|build)" | head -20Repository: opendatahub-io/ai-helpers
Length of output: 264
🏁 Script executed:
find . -type f \( -name ".github" -o -name "docker-compose*" \) | head -20Repository: opendatahub-io/ai-helpers
Length of output: 51
🏁 Script executed:
cd images/cursor && ls -laRepository: opendatahub-io/ai-helpers
Length of output: 242
🏁 Script executed:
cat -n images/cursor/ContainerfileRepository: opendatahub-io/ai-helpers
Length of output: 2949
🏁 Script executed:
cat -n .github/workflows/build.ymlRepository: opendatahub-io/ai-helpers
Length of output: 2387
🏁 Script executed:
web_search
OpenShift mirror openshift-client-linux artifact naming conventions amd64 arm64Repository: opendatahub-io/ai-helpers
Length of output: 167
🌐 Web query:
OpenShift client mirror openshift-client-linux-arm64.tar.gz amd64 arm64 artifacts
💡 Result:
OpenShift oc client tarballs are published on the public mirror under these patterns (pick either a specific version directory like 4.17.17/ or a moving channel like stable/, stable-4.14/, latest-4.16/, etc.):
Linux amd64 (x86_64)
https://mirror.openshift.com/pub/openshift-v4/x86_64/clients/ocp/<channel-or-version>/openshift-client-linux.tar.gz
Red Hat docs also reference this ${ARCH} form (where ${ARCH} is x86_64, aarch64, etc.). (docs.redhat.com)
Linux arm64 (aarch64)
Commonly published as an explicit arm64 filename:
https://mirror.openshift.com/pub/openshift-v4/clients/ocp/<channel-or-version>/openshift-client-linux-arm64.tar.gz
Examples seen in the wild:
.../stable/openshift-client-linux-arm64.tar.gz(learn.arm.com).../4.17.17/openshift-client-linux-arm64.tar.gz(docs.wakemeops.com)
“Multi” layout (also used for arch-separated listings)
You may also find arch-separated directories like:
https://mirror.openshift.com/pub/openshift-v4/multi/clients/ocp/stable/amd64/
Citations:
- 1: https://docs.redhat.com/en-us/documentation/openshift_container_platform/4.16/pdf/installing_on_a_single_node/OpenShift_Container_Platform-4.16-Installing_on_a_single_node-en-US.pdf?utm_source=openai
- 2: https://learn.arm.com/install-guides/oc/?utm_source=openai
- 3: https://docs.wakemeops.com/packages/oc/?utm_source=openai
- 4: https://mirror.openshift.com/pub/openshift-v4/multi/clients/ocp/stable/amd64/?utm_source=openai
Major: oc binary download must be architecture-aware for multi-arch builds.
The build workflow (.github/workflows/build.yml:68) publishes for both linux/amd64 and linux/arm64, but the Containerfile hardcodes the generic amd64 archive. The OpenShift mirror publishes distinct artifacts: openshift-client-linux.tar.gz (amd64) and openshift-client-linux-arm64.tar.gz (arm64). The arm64 image will receive the amd64 binary, causing runtime failures.
Parameterize the archive name using Docker's TARGETARCH build argument before publishing multi-arch images:
Remediation
+ARG TARGETARCH
-RUN curl -LsSf https://mirror.openshift.com/pub/openshift-v4/clients/ocp/stable/openshift-client-linux.tar.gz | tar xzf - -C /usr/local/bin/ oc \
- && chmod +x /usr/local/bin/oc
+RUN case "${TARGETARCH}" in \
+ amd64) oc_archive="openshift-client-linux.tar.gz" ;; \
+ arm64) oc_archive="openshift-client-linux-arm64.tar.gz" ;; \
+ *) echo "Unsupported TARGETARCH=${TARGETARCH}" >&2; exit 1 ;; \
+ esac \
+ && curl -fsSLo /tmp/oc.tgz "https://mirror.openshift.com/pub/openshift-v4/clients/ocp/stable/${oc_archive}" \
+ && tar xzf /tmp/oc.tgz -C /usr/local/bin/ oc \
+ && chmod +x /usr/local/bin/oc \
+ && rm -f /tmp/oc.tgz🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@images/cursor/Containerfile` around lines 35 - 36, The Containerfile
currently hardcodes the amd64 OpenShift client archive in the RUN curl ... oc
download line, which breaks arm64 multi-arch images; add a build ARG TARGETARCH
at the top of the Containerfile and use it to choose the correct archive name
when downloading the oc binary (e.g., map TARGETARCH to the archive suffix such
that TARGETARCH=arm64 selects openshift-client-linux-arm64.tar.gz and otherwise
selects openshift-client-linux.tar.gz), and then update the RUN curl ...
/usr/local/bin/oc command to reference that computed archive variable so
multi-arch builds pull the correct binary.
| @echo "Building Claude container image $(CLAUDE_IMAGE_NAME):$(IMAGE_TAG) with $(CONTAINER_RUNTIME)..." | ||
| $(CONTAINER_RUNTIME) build -f images/claude/Containerfile -t $(CLAUDE_IMAGE_NAME):$(IMAGE_TAG) . | ||
|
|
||
| .PHONY: build-cursor | ||
| build-cursor: ## Build Cursor CLI container image | ||
| @echo "Building Cursor container image $(CURSOR_IMAGE_NAME):$(IMAGE_TAG) with $(CONTAINER_RUNTIME)..." | ||
| $(CONTAINER_RUNTIME) build -f images/cursor/Containerfile -t $(CURSOR_IMAGE_NAME):$(IMAGE_TAG) . |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Find and read the Makefile
fd -name Makefile -type f | head -5Repository: opendatahub-io/ai-helpers
Length of output: 299
🏁 Script executed:
# Read the Makefile to see the full context
if [ -f Makefile ]; then
wc -l Makefile
cat -n Makefile
fiRepository: opendatahub-io/ai-helpers
Length of output: 3695
Quote the image reference in build targets.
IMAGE_TAG, CLAUDE_IMAGE_NAME, and CURSOR_IMAGE_NAME are overrideable from the environment/CLI. Per the Makefile security guideline, quote shell variables in targets to prevent word-splitting.
Remediation
- $(CONTAINER_RUNTIME) build -f images/claude/Containerfile -t $(CLAUDE_IMAGE_NAME):$(IMAGE_TAG) .
+ $(CONTAINER_RUNTIME) build -f images/claude/Containerfile -t "$(CLAUDE_IMAGE_NAME):$(IMAGE_TAG)" .
- $(CONTAINER_RUNTIME) build -f images/cursor/Containerfile -t $(CURSOR_IMAGE_NAME):$(IMAGE_TAG) .
+ $(CONTAINER_RUNTIME) build -f images/cursor/Containerfile -t "$(CURSOR_IMAGE_NAME):$(IMAGE_TAG)" .📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| @echo "Building Claude container image $(CLAUDE_IMAGE_NAME):$(IMAGE_TAG) with $(CONTAINER_RUNTIME)..." | |
| $(CONTAINER_RUNTIME) build -f images/claude/Containerfile -t $(CLAUDE_IMAGE_NAME):$(IMAGE_TAG) . | |
| .PHONY: build-cursor | |
| build-cursor: ## Build Cursor CLI container image | |
| @echo "Building Cursor container image $(CURSOR_IMAGE_NAME):$(IMAGE_TAG) with $(CONTAINER_RUNTIME)..." | |
| $(CONTAINER_RUNTIME) build -f images/cursor/Containerfile -t $(CURSOR_IMAGE_NAME):$(IMAGE_TAG) . | |
| `@echo` "Building Claude container image $(CLAUDE_IMAGE_NAME):$(IMAGE_TAG) with $(CONTAINER_RUNTIME)..." | |
| $(CONTAINER_RUNTIME) build -f images/claude/Containerfile -t "$(CLAUDE_IMAGE_NAME):$(IMAGE_TAG)" . | |
| .PHONY: build-cursor | |
| build-cursor: ## Build Cursor CLI container image | |
| `@echo` "Building Cursor container image $(CURSOR_IMAGE_NAME):$(IMAGE_TAG) with $(CONTAINER_RUNTIME)..." | |
| $(CONTAINER_RUNTIME) build -f images/cursor/Containerfile -t "$(CURSOR_IMAGE_NAME):$(IMAGE_TAG)" . |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@Makefile` around lines 65 - 71, Quote shell variables used in the image
reference to prevent word-splitting: update the Claude and Cursor build targets
(the echo lines and the build commands that use $(CONTAINER_RUNTIME),
$(CLAUDE_IMAGE_NAME), $(CURSOR_IMAGE_NAME), and $(IMAGE_TAG)) so the image tags
are quoted, e.g. use "$(CLAUDE_IMAGE_NAME):$(IMAGE_TAG)" and
"$(CURSOR_IMAGE_NAME):$(IMAGE_TAG)" in the -t arguments and in the echo
messages; keep $(CONTAINER_RUNTIME) invocation intact but ensure the image
references are wrapped in double quotes to avoid splitting.
| To use the Cursor Agent CLI, you need to pass your `CURSOR_API_KEY`: | ||
|
|
||
| ```bash | ||
| podman run -it --rm \ | ||
| --pull newer \ | ||
| --userns=keep-id \ | ||
| -e CURSOR_API_KEY=your-api-key \ | ||
| -v $(pwd):$(pwd):z \ | ||
| -w $(pwd) \ | ||
| ghcr.io/opendatahub-io/ai-helpers-cursor:latest |
There was a problem hiding this comment.
Major: both examples expose CURSOR_API_KEY in host process args (CWE-312/CWE-200).
Inlining the value in podman run — including "${CURSOR_API_KEY}" in the helper — expands the secret into the spawned command line. That leaks it via ps, and the one-off example also encourages shell-history exposure. Pass the variable name through instead.
Remediation
- -e CURSOR_API_KEY=your-api-key \
+ -e CURSOR_API_KEY \
...
- -e CURSOR_API_KEY="${CURSOR_API_KEY}" \
+ -e CURSOR_API_KEY \Also applies to: 233-241
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@README.md` around lines 215 - 224, The examples in README.md inline the
actual CURSOR_API_KEY value into the podman run command which leaks secrets via
process args; change both examples (the podman run snippets around the shown
block and the later one at 233-241) to avoid embedding the secret by passing
only the variable name (e.g., use -e CURSOR_API_KEY or --env CURSOR_API_KEY
without "=your-api-key"), or show using an env file (--env-file .env) or
prompting to export CURSOR_API_KEY in the shell beforehand, so the command no
longer contains the secret literal.
|
I'll go with the PR as is and we can improve later. |
Pull Request Description
Summary
Add a second container image for Cursor's Agent CLI alongside the
existing Claude Code CLI image. The build workflow now uses a matrix
strategy to build both images in parallel, and the Makefile supports
individual (build-claude, build-cursor) or combined (build) targets.
The Cursor image is published as ghcr.io/opendatahub-io/ai-helpers-cursor
and shares the same base tooling (Fedora, Node.js, Python, uv, gcloud,
oc) as the Claude image.
Test:
Type of Contribution
Summary by CodeRabbit
New Features
Documentation
Build & Infrastructure