Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ jobs:
- profile: sandbox-stackrox-ci
tag_prefix: sandbox-stackrox-ci
platforms: linux/amd64
- profile: sandbox-collector-builder
tag_prefix: sandbox-collector-builder
platforms: linux/amd64
env:
IMAGE_PROFILE: ${{ matrix.profile }}
IMAGE_TAG_PREFIX: ${{ matrix.tag_prefix }}
Expand Down
23 changes: 23 additions & 0 deletions profiles/stackrox/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,26 @@ docker build --platform linux/amd64 \
-t quay.io/rcochran/openshell:sandbox-stackrox-ci \
profiles/stackrox/image/sandbox-stackrox-ci
```

### `sandbox-collector-builder`

An amd64 image based on the StackRox Collector builder image. The `master`
builder manifest is pinned to
`sha256:52a3cca5253abb0cd5c3606769d5fd5b8be4cdb4671396f38a792695f07d7696`.
It keeps the Collector compiler and build toolchain and adds the same
OpenShell contract, coding agents, GitHub skill, Atlassian MCP, Google
Workspace CLI, and `gopls` support as the StackRox CI profile. It is separate
from `sandbox-stackrox-ci` so workflows can choose the Collector-specific
toolchain without changing the Apollo/rox-ci-image profile.

The base image is multi-architecture, but several bundled third-party
binaries are currently amd64-only, so this profile is published for
`linux/amd64` only.

Build it locally with:

```bash
docker build --platform linux/amd64 \
-t quay.io/rcochran/openshell:sandbox-collector-builder \
profiles/stackrox/image/sandbox-collector-builder
```
25 changes: 25 additions & 0 deletions profiles/stackrox/image/sandbox-collector-builder/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Sandbox Environment

You are running inside an OpenShell sandbox based on the StackRox Collector
`collector-builder` image. Credentials are injected by OpenShell providers and
are not part of the image.

## Environment

- Working directory: `/sandbox`
- Writable paths: `/sandbox`, `/tmp`
- Inference routes through the gateway proxy at `inference.local`

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Dockerfile for this image (line 136) states that the collector-builder base image does not include Go, and then proceeds to install it. This documentation contradicts the Dockerfile by stating that Go is available from the base image. Please clarify whether the base image includes Go and update the documentation to be consistent.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved in the current head: the image instructions now say that the Collector builder supplies the C/C++ build tools and this profile adds the pinned Go toolchain and gopls.

- Repository build tools from the `collector-builder` build are available,
including compilers, make, git, jq, and the StackRox CI toolchain. This
profile adds the pinned Go toolchain and `gopls` for Go repository analysis.

## Tools

- `gh` — GitHub CLI. Use the bundled GitHub skill for REST-only API access.
- `gws` — Google Workspace CLI when the provider is attached.
- `python3`, `uv`, `node`, `npm`, `go`, `gopls`, `ajv`, `git`, `curl`
- `claude`, `opencode`, `codex`, and `copilot` coding agents
- Atlassian and Go-analysis MCP servers through `.mcp.json` when configured

The OpenShell Vertex provider supplies model access and credentials. The image
does not install `gcloud` or copy service-account keys into the sandbox.
195 changes: 195 additions & 0 deletions profiles/stackrox/image/sandbox-collector-builder/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
# syntax=docker/dockerfile:1.4

# StackRox collector-builder sandbox image for OpenShell repository workflows.
#
# This profile starts from the latest StackRox Collector builder image so
# collector build tools (Go, compilers, make, and the collector toolchain) are
# available to the agent. It adds the OpenShell sandbox contract, coding-agent
# tools, and selected vendored OpenShell assets.
#
# The collector builder is multi-architecture, but the bundled Claude and
# Google Workspace binaries are amd64-only. Keep this profile amd64-only until
# those downloads are made architecture-aware.
#
# Base image source:
# https://github.com/stackrox/collector/tree/master/builder
# OpenShell base contract:
# https://github.com/NVIDIA/OpenShell-Community/tree/main/sandboxes/base

# The tag is master; pin the current multi-architecture manifest digest
# so a retag cannot silently change the toolchain.
ARG BASE_IMAGE=quay.io/stackrox-io/collector-builder@sha256:52a3cca5253abb0cd5c3606769d5fd5b8be4cdb4671396f38a792695f07d7696
FROM ${BASE_IMAGE}

SHELL ["/bin/bash", "-o", "pipefail", "-c"]

USER root

# Runtime tools used by the OpenShell sandbox contract and by agent skills.
# collector-builder image already supplies the compiler toolchain, Go, git, jq,
# and curl. Add Node/npm for the coding-agent CLIs, plus the missing runtime
# pieces needed by the OpenShell sandbox contract.
RUN dnf install -y --setopt=install_weak_deps=False \
ca-certificates \
findutils \
gzip \
iproute \
iputils \
nano \
net-tools \
nmap-ncat \
nodejs \
npm \
openssh-clients \
perl-Digest-SHA \
procps-ng \
shadow-utils \
tar \
vim-minimal \
wget \
which \
&& dnf clean all \
&& rm -rf /var/cache/dnf

# OpenShell expects an unprivileged sandbox user with a writable home and a
# supervisor account available for images that need privileged setup.
RUN groupadd -r supervisor \
&& useradd -r -g supervisor -s /sbin/nologin supervisor \
&& groupadd -r sandbox \
&& useradd -r -g sandbox -d /sandbox -s /bin/bash sandbox \
&& mkdir -p /sandbox \
&& chown sandbox:sandbox /sandbox

# GitHub CLI (collector-builder image does not include it). Pin the release and verify it
# before installing so the image remains reproducible.
ARG GH_VERSION=2.100.0
ARG GH_SHA256_AMD64=e4d4bb4498e8d007abe545b6568926793ace1b6447da598294a610018cb164be
RUN curl -fsSL "https://github.com/cli/cli/releases/download/v${GH_VERSION}/gh_${GH_VERSION}_linux_amd64.tar.gz" -o /tmp/gh.tgz \
&& echo "${GH_SHA256_AMD64} /tmp/gh.tgz" | sha256sum -c - \
&& mkdir -p /tmp/gh-extract \
&& tar -xzf /tmp/gh.tgz --strip-components=2 -C /tmp/gh-extract "gh_${GH_VERSION}_linux_amd64/bin/gh" \
&& test -f /tmp/gh-extract/gh \
&& install -m 0755 /tmp/gh-extract/gh /usr/bin/gh \
&& rm -rf /tmp/gh-extract /tmp/gh.tgz

# Use the same uv-managed Python contract as the community base image. The
# collector-builder image system Python is 3.9, while current MCP integrations require
# 3.10+.
COPY --from=ghcr.io/astral-sh/uv:0.10.8 /uv /usr/local/bin/uv
ARG PYTHON_VERSION=3.14.3
ENV UV_PYTHON_INSTALL_DIR=/sandbox/.uv/python
RUN uv python install "${PYTHON_VERSION}" \
&& uv cache clean

# Coding agents and the JSON-schema utility used by StackRox workflows. These
# versions mirror the current StackRox sandbox profile where applicable.
ARG NPM_HONO_VERSION=1.19.11

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Python version 3.14.3 does not appear to be a valid or available Python version. This will cause the uv python install command to fail. Please correct this to a valid Python version, for example a recent 3.12.x release.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skipped: this finding is incorrect. uv python install 3.14.3 completed successfully in the StackRox image build; the version is available from uv and is intentional for the MCP runtime.

ARG NPM_OPENCODE_VERSION=1.18.30
ARG NPM_CODEX_VERSION=0.117.0
ARG NPM_COPILOT_VERSION=1.0.16
ARG NPM_AJV_VERSION=5.0.0

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Python version 3.14.3 is not a valid or available Python version. This will cause the Docker build to fail. You should use a valid version, for example, the latest stable version from the 3.12 series.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skipped: this repeats the incorrect Python finding. uv python install 3.14.3 completed successfully in the final image build, so the pinned version is valid.

RUN mkdir -p /tmp/npm-global \
&& chown sandbox:sandbox /tmp/npm-global
USER sandbox
RUN NPM_CONFIG_PREFIX=/tmp/npm-global npm install -g \
"@hono/node-server@${NPM_HONO_VERSION}" \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Python version 3.14.3 does not exist. This will cause the build to fail. This is likely a typo and should be a valid Python version, for example 3.12.3.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skipped: this repeated finding is incorrect. uv python install 3.14.3 completed successfully in the image build, so the pinned Python version is valid.

"opencode-ai@${NPM_OPENCODE_VERSION}" \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The uv version 0.10.8 is significantly outdated. As a fast-developing tool, using a more recent version is recommended to benefit from performance improvements, security updates, and bug fixes. Please consider updating to a newer release.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skipped: this profile pins uv 0.10.8 for reproducible image builds and uses the same tested version as the StackRox CI profile. Updating it is a separate dependency-refresh change, not a correctness issue for this PR.

"@openai/codex@${NPM_CODEX_VERSION}" \
"@github/copilot@${NPM_COPILOT_VERSION}" \
"ajv-cli@${NPM_AJV_VERSION}" \
&& npm cache clean --force
USER root
RUN cp -a /tmp/npm-global/lib/node_modules/. /usr/lib/node_modules/ \
&& for name in opencode codex copilot ajv; do \
test -e "/tmp/npm-global/bin/${name}"; \
cp -a "/tmp/npm-global/bin/${name}" "/usr/bin/${name}"; \
chown -h root:root "/usr/bin/${name}"; \
done \
&& chown -R root:root /usr/lib/node_modules \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The build argument NPM_HONO_VERSION is defined on line 102, but the corresponding package, @hono/node-server, is not included in this npm install command. This appears to be an omission.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skipped: @hono/node-server is included in the current npm install command. The finding targets a stale view of the file.

&& rm -rf /tmp/npm-global

# Claude Code's native binary. Pin both the release URL and its release
# manifest checksum instead of executing a downloaded installer as root.
ARG CLAUDE_VERSION=2.1.269
ARG CLAUDE_SHA256_AMD64=25e44883f54419569a3d739f38cbbdaebe83b09895da0f343e1b003710a4775b
RUN curl -fsSL "https://downloads.claude.ai/claude-code-releases/${CLAUDE_VERSION}/linux-x64/claude" -o /tmp/claude \
&& echo "${CLAUDE_SHA256_AMD64} /tmp/claude" | sha256sum -c - \
&& install -m 0755 /tmp/claude /usr/local/bin/claude \
&& rm -f /tmp/claude

# Go-language MCP support for repository analysis. The Collector builder image
# supplies C/C++ build tooling but not Go, so install the pinned Go toolchain
# before building gopls.
ARG GO_VERSION=1.24.2
ARG GO_SHA256_AMD64=68097bd680839cbc9d464a0edce4f7c333975e27a90246890e9f1078c7e702ad
RUN curl -fsSL "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz" -o /tmp/go.tgz \
&& echo "${GO_SHA256_AMD64} /tmp/go.tgz" | sha256sum -c - \
&& tar -C /usr/local -xzf /tmp/go.tgz \
&& rm -f /tmp/go.tgz

ARG GOPLS_VERSION=0.20.0
RUN GOPATH=/tmp/gopath GOCACHE=/tmp/gocache GOBIN=/usr/local/bin \
/usr/local/go/bin/go install "golang.org/x/tools/gopls@v${GOPLS_VERSION}" \
&& rm -rf /tmp/gopath /tmp/gocache

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The base collector-builder image and surrounding documentation state that a Go toolchain is already included. This redundant go installation adds to the image size and may introduce version conflicts. Consider removing this installation and using the go provided by the base image.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved in the current head: the Collector builder image does not include Go, so this profile now installs the pinned Go 1.24.2 toolchain before building gopls.

# Atlassian MCP is part of the StackRox workflow image contract. The gateway
# still owns credentials; no credential values are baked into this image.
RUN uv venv --python "${PYTHON_VERSION}" --seed /sandbox/.venv \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pinned Go version 1.24.2 is several major versions behind current stable releases and is likely unsupported. Please update to a recent, supported Go version to ensure security patches and bug fixes are included.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skipped: Go 1.24.2 is intentionally pinned with its checksum and is the tested version shared with the default StackRox profile. Updating the toolchain is a separate dependency-refresh change.

&& uv pip install --python /sandbox/.venv/bin/python \
cloudpickle==3.1.2 \
mcp-atlassian==0.21.1 \
&& uv cache clean

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The go install command populates a build cache (typically in /root/.cache/go-build when run as root). This cache is not being cleaned in this step. Consider adding go clean -cache -modcache after installing gopls to reduce the final image size.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved in the current head: the gopls install now removes /root/go and /root/.cache/go-build in the same layer.

# Google Workspace CLI is used by StackRox workflows when the corresponding
# OpenShell provider is attached. Use the static musl build so it runs on the
# CentOS glibc version supplied by collector-builder.
ARG GWS_VERSION=0.22.5
ARG GWS_SHA256_AMD64=4db473dde4b1ab872e4ff35d769b0d4af1f1a6441a605e79d5cf8ada9c87e920

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The go install command for gopls does not pin the version, which can lead to non-reproducible builds. It is recommended to use a specific version tag to ensure build consistency.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skipped: the version is pinned through ARG GOPLS_VERSION=0.20.0 and the install uses golang.org/x/tools/gopls@v${GOPLS_VERSION}. The finding targets a stale view of the file.

RUN curl -fsSL "https://github.com/googleworkspace/cli/releases/download/v${GWS_VERSION}/google-workspace-cli-x86_64-unknown-linux-musl.tar.gz" -o /tmp/gws.tgz \
&& echo "${GWS_SHA256_AMD64} /tmp/gws.tgz" | sha256sum -c - \
&& mkdir -p /tmp/gws-extract \
&& tar xzf /tmp/gws.tgz --no-same-owner --no-same-permissions -C /tmp/gws-extract ./gws \
&& test -f /tmp/gws-extract/gws \
&& install -m 0755 /tmp/gws-extract/gws /usr/local/bin/gws \
&& rm -rf /tmp/gws-extract \
&& rm -f /tmp/gws.tgz

ENV PATH="/sandbox/.venv/bin:/usr/local/go/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin" \
VIRTUAL_ENV=/sandbox/.venv \
GOPATH=/sandbox/.cache/go \
GOCACHE=/sandbox/.cache/go-build \
GOMODCACHE=/sandbox/.cache/go-mod

# Vendor only the small OpenShell assets this profile uses. The upstream
# network policy is intentionally not inherited; this profile owns its small
# StackRox policy and provider profiles supply integration egress at runtime.
COPY openshell/skills/ /sandbox/.agents/skills/
COPY openshell/.bashrc /sandbox/.bashrc
COPY openshell/.profile /sandbox/.profile
COPY policy.yaml /etc/openshell/policy.yaml

# Default agent instructions and configuration. Workflows can override these
# files with payloads for repository-specific skills and instructions.
COPY CLAUDE.md /sandbox/.claude/CLAUDE.md
COPY settings.json /sandbox/.claude/settings.json
COPY claude.json /sandbox/.claude.json
COPY mcp.json /sandbox/.mcp.json
COPY opencode.json /sandbox/opencode.json

RUN mkdir -p /sandbox/.claude/skills /sandbox/.config/openshell \
&& chmod 0644 /etc/openshell/policy.yaml \
/sandbox/.claude/CLAUDE.md \
/sandbox/.claude/settings.json \
/sandbox/.claude.json \
/sandbox/.mcp.json \
/sandbox/opencode.json \
&& for skill in /sandbox/.agents/skills/*/; do \
[ -d "${skill}" ] || continue; \
ln -sf "${skill}" "/sandbox/.claude/skills/$(basename "${skill}")"; \
done \
&& chown -R sandbox:sandbox /sandbox

WORKDIR /sandbox
USER sandbox

ENTRYPOINT ["/bin/bash"]
14 changes: 14 additions & 0 deletions profiles/stackrox/image/sandbox-collector-builder/claude.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"hasCompletedOnboarding": true,
"numStartups": 1,
"autoUpdates": false,
"customApiKeyResponses": {
"approved": ["nshell-proxy-managed"]
},
"projects": {
"/sandbox": {
"hasTrustDialogAccepted": true,
"allowedTools": []
}
}
}
17 changes: 17 additions & 0 deletions profiles/stackrox/image/sandbox-collector-builder/mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"mcpServers": {
"atlassian": {
"type": "stdio",
"command": "/sandbox/.venv/bin/mcp-atlassian",
"args": [],
"env": {
"READ_ONLY_MODE": "true"
}
},
"gopls-mcp": {
"type": "stdio",
"command": "/usr/local/bin/gopls",
"args": ["mcp"]
}
}
}
18 changes: 18 additions & 0 deletions profiles/stackrox/image/sandbox-collector-builder/opencode.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"atlassian": {
"type": "local",
"command": ["/sandbox/.venv/bin/mcp-atlassian"],
"enabled": true,
"environment": {
"READ_ONLY_MODE": "true"
}
},
"gopls-mcp": {
"type": "local",
"command": ["/usr/local/bin/gopls", "mcp"],
"enabled": true
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export PATH="/sandbox/.venv/bin:/usr/local/go/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
export VIRTUAL_ENV="/sandbox/.venv"
export UV_PYTHON_INSTALL_DIR="/sandbox/.uv/python"
export GOPATH="/sandbox/.cache/go"
export GOCACHE="/sandbox/.cache/go-build"
export GOMODCACHE="/sandbox/.cache/go-mod"
export PS1="\u@\h:\w\$ "
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[ -f ~/.bashrc ] && . ~/.bashrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Vendored OpenShell assets

This directory contains the small set of files copied from the NVIDIA
OpenShell Community base sandbox that this profile uses at runtime:

- the GitHub REST-only agent skill;
- shell initialization adapted from the upstream base image for the StackRox
Go toolchain and writable caches.

Source: `NVIDIA/OpenShell-Community/sandboxes/base` at commit
`fffb6b2248ff6ba585f50517f3711b08122089f2`.

The source repository is Apache-2.0 licensed. Keep this copy synchronized with
the pinned source commit when the upstream base contract changes. The upstream
network policy is intentionally not copied; this profile owns its minimal
policy and provider profiles supply integration egress at runtime.
Loading
Loading