feat(api): env-configurable box image allowlist - #1027
Conversation
Add BOXLITE_SYSTEM_IMAGES so operators can extend the curated box-image set (comma-separated `name=ref`) without a code deploy. Each image now carries a short name and an OCI ref; a create-time selector resolves by name or full ref to the ref, keeping persist / warm-pool / runner on opaque refs. The built-in base/python/node refs stay env-overridable and base remains the default. A malformed entry throws at the boundary. Claude-Session: https://claude.ai/code/session_01YFLhjZmRUvDUFtwBp9wELy
📦 BoxLite review — 1 issue ·
|
|
tester seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
|
Caution Review failedFailed to post review comments. We encountered an issue with GitHub. Use ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
⏰ Context from checks skipped due to timeout. (8)
🧰 Additional context used📓 Path-based instructions (3)apps/infra/**/*.{py,js,ts,tsx,java,go,rb,php}📄 CodeRabbit inference engine (apps/infra/AGENTS.md)
Files:
apps/infra/**/*.{py,js,ts,tsx,json,yaml,yml}📄 CodeRabbit inference engine (apps/infra/AGENTS.md)
Files:
apps/infra/**/{README,*.md,*.env*,*.config.*,*.conf}📄 CodeRabbit inference engine (apps/infra/AGENTS.md)
Files:
🧠 Learnings (1)📚 Learning: 2026-06-29T04:50:08.549ZApplied to files:
📝 WalkthroughWalkthroughCurated image selection now supports built-in names, full OCI references, environment overrides, and operator-defined ChangesCurated image allowlisting
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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 |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/api/src/box/constants/curated-images.constant.ts`:
- Around line 80-85: The supportedImages() allowlist currently permits duplicate
names, causing assertSupportedImage() to resolve the first match. After
combining builtins with parseExtraImages(), validate that every image name is
unique and reject duplicate built-in/custom and duplicate-extra entries;
preserve the existing returned image list for valid configuration.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 3cef0417-0f93-41bc-b403-bcd21a861980
📒 Files selected for processing (4)
apps/api/src/box/constants/curated-images.constant.spec.tsapps/api/src/box/constants/curated-images.constant.tsapps/api/src/box/dto/create-box.dto.tsapps/infra/sst.config.ts
| export function supportedImages(): SupportedImage[] { | ||
| const builtins = BUILTIN_IMAGE_SOURCES.map(({ name, envVar, fallbackRef }) => ({ | ||
| name, | ||
| ref: process.env[envVar] || fallbackRef, | ||
| })) | ||
| return [...builtins, ...parseExtraImages(process.env[EXTRA_IMAGES_ENV])] |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Reject duplicate image names before returning the allowlist.
assertSupportedImage() uses find(), so BOXLITE_SYSTEM_IMAGES=base=... or two hermes=... entries silently resolve the first entry instead of failing configuration. Validate unique names after combining built-ins and extras; add duplicate built-in/custom and duplicate-extra tests.
Suggested fix
export function supportedImages(): SupportedImage[] {
const builtins = BUILTIN_IMAGE_SOURCES.map(({ name, envVar, fallbackRef }) => ({
name,
ref: process.env[envVar] || fallbackRef,
}))
- return [...builtins, ...parseExtraImages(process.env[EXTRA_IMAGES_ENV])]
+ const images = [...builtins, ...parseExtraImages(process.env[EXTRA_IMAGES_ENV])]
+ const names = new Set<string>()
+ for (const { name } of images) {
+ if (names.has(name)) {
+ throw new Error(`Duplicate supported image name '${name}'`)
+ }
+ names.add(name)
+ }
+ return images
}📝 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.
| export function supportedImages(): SupportedImage[] { | |
| const builtins = BUILTIN_IMAGE_SOURCES.map(({ name, envVar, fallbackRef }) => ({ | |
| name, | |
| ref: process.env[envVar] || fallbackRef, | |
| })) | |
| return [...builtins, ...parseExtraImages(process.env[EXTRA_IMAGES_ENV])] | |
| export function supportedImages(): SupportedImage[] { | |
| const builtins = BUILTIN_IMAGE_SOURCES.map(({ name, envVar, fallbackRef }) => ({ | |
| name, | |
| ref: process.env[envVar] || fallbackRef, | |
| })) | |
| const images = [...builtins, ...parseExtraImages(process.env[EXTRA_IMAGES_ENV])] | |
| const names = new Set<string>() | |
| for (const { name } of images) { | |
| if (names.has(name)) { | |
| throw new Error(`Duplicate supported image name '${name}'`) | |
| } | |
| names.add(name) | |
| } | |
| return images | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/api/src/box/constants/curated-images.constant.ts` around lines 80 - 85,
The supportedImages() allowlist currently permits duplicate names, causing
assertSupportedImage() to resolve the first match. After combining builtins with
parseExtraImages(), validate that every image name is unique and reject
duplicate built-in/custom and duplicate-extra entries; preserve the existing
returned image list for valid configuration.
What
Make the box-image allowlist configurable from env so images can be added
without a code deploy.
BOXLITE_SYSTEM_IMAGES(comma-separatedname=ref) appends images to thebuilt-in
base/python/nodeset;basestays the default.{ name, ref }; a create-time selector resolves by name or fullOCI ref to the ref, so persist / warm-pool / runner stay on opaque refs.
name=refentry throws at the request boundary (operator config).Verification
string[]code fails the new spec).tsc --noEmiton the api app source clean; sole consumerbox.service.ts:175keeps the same
stringreturn.POST /api/v1/boxes):hermesaccepted by name and byfull ref (persisted as the resolved ref), unknowns rejected with the full
supported list, omitted image defaults to base.
Note: actually booting
sam2026go/hermes-agent:boxliteneeds a linux/arm64image build (currently amd64-only) — out of scope for this allowlist change.
https://claude.ai/code/session_01YFLhjZmRUvDUFtwBp9wELy
Summary by CodeRabbit
New Features
BOXLITE_SYSTEM_IMAGESusingname=refentries.Bug Fixes
Documentation
baseimage.