Skip to content

fix(hub): harden release image dependencies - #11

Merged
crs48 merged 1 commit into
mainfrom
codex/hub-security-image-fix
Mar 9, 2026
Merged

fix(hub): harden release image dependencies#11
crs48 merged 1 commit into
mainfrom
codex/hub-security-image-fix

Conversation

@crs48

@crs48 crs48 commented Mar 9, 2026

Copy link
Copy Markdown
Owner

Summary

  • install patched @hono/node-server@1.19.10 and hono@4.12.4 in the hub runtime image
  • disable automatic optional peer installation so the Expo sqlite stack is not pulled into the server image
  • remove npm and Corepack artifacts from the final runtime layer to drop vulnerable package-manager libraries from the scan

Validation

  • reproduced the runtime-stage install in a clean temp workspace and confirmed the resulting pnpm store contained patched Hono packages and did not contain expo, tar, minimatch, glob, or diff
  • attempted corepack pnpm --filter @xnetjs/hub test, but the current checkout fails earlier on unresolved internal workspace package entries and does not exercise this Docker-only change
  • could not run a full docker build here because the Docker daemon is not running in this environment

Summary by CodeRabbit

  • Chores
    • Optimized the Docker runtime image: selected runtime web-server dependencies and rebuilt the native database driver.
    • Disabled automatic peer dependency installation for more deterministic builds.
    • Aggressively removed build tools, package managers and caches while preserving application artifacts to reduce image size and surface fewer runtime files.

@coderabbitai

coderabbitai Bot commented Mar 9, 2026

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1a734861-8e62-4ba5-978f-85d275b06575

📥 Commits

Reviewing files that changed from the base of the PR and between 3660fbf and 49c57b8.

📒 Files selected for processing (1)
  • packages/hub/Dockerfile

📝 Walkthrough

Walkthrough

The runtime stage of packages/hub/Dockerfile now replaces a generic pnpm install with targeted corepack pnpm add for specific Hono packages, disables peer auto-installation, rebuilds better-sqlite3 with the same filter, and adds aggressive cleanup of build deps, package manager binaries, and caches to slim the image. (50 words)

Changes

Cohort / File(s) Summary
Hub Runtime Dockerfile
packages/hub/Dockerfile
Replaced pnpm install with corepack pnpm add for @hono/node-server@1.19.10 and hono@4.12.4 scoped to @xnetjs/hub, disabled auto-install of peer deps, rebuilt better-sqlite3 with the same filter, retained hub artifact copy, and added removal of build deps, Corepack/PNPM/npm binaries, and caches.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐇 I nibbled installs, picked Hono with care,
Cleared crumbs of caches from corners of air,
Rebuilt tiny engines, packed only what's true,
A lighter hub runtime — hop, ship it anew! 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(hub): harden release image dependencies' directly and specifically addresses the main change—hardening hub release image dependencies by updating Hono packages and removing package-manager artifacts.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/hub-security-image-fix

Comment @coderabbitai help to get the list of available commands and usage tips.

- install the hub runtime dependencies with patched Hono releases in the image build

- disable automatic optional peer installation so the Expo sqlite stack is not pulled into the server image

- remove npm and corepack artifacts from the final runtime layer to eliminate vulnerable package-manager libraries
@crs48
crs48 force-pushed the codex/hub-security-image-fix branch from 3660fbf to 49c57b8 Compare March 9, 2026 21:51
@crs48
crs48 merged commit 061d2d1 into main Mar 9, 2026
6 of 7 checks passed
@greptile-apps

greptile-apps Bot commented Mar 9, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR hardens the hub Docker runtime image by pinning patched versions of @hono/node-server@1.19.10 and hono@4.12.4, disabling optional peer auto-installation, and stripping npm/corepack binaries and caches from the final layer to reduce the vulnerable-package surface area.

  • The core security intent is sound: forcing newer, patched Hono releases and removing package-manager tooling from the scanned runtime image.
  • The replacement of pnpm install --frozen-lockfile --prod --filter @xnetjs/hub... with pnpm add ... --filter @xnetjs/hub drops --frozen-lockfile and the workspace-recursive ... filter. This may leave workspace dependency packages (@xnetjs/core, @xnetjs/crypto, etc.) without their own production deps fully set up, and allows pnpm to re-resolve transitive deps outside the lockfile if peer conflicts arise.
  • The pnpm global content store (typically /root/.local/share/pnpm/store) is not removed in the cleanup step, leaving duplicate package data in the final image layer and partially undermining the goal of a lean, clean runtime image.

Confidence Score: 3/5

  • Mergeable with low-to-medium risk, but the install command change should be validated under a live Docker build before shipping to production.
  • The security motivation is clear and the cleanup steps are correct. However, the behavioral difference between pnpm install --frozen-lockfile --prod --filter @xnetjs/hub... and pnpm add --filter @xnetjs/hub (no --frozen-lockfile, no ... recursion) has not been exercised with an actual docker build (per the PR description), leaving uncertainty about whether all workspace-package transitive deps are properly installed in the runtime image.
  • packages/hub/Dockerfile — specifically the pnpm add invocation and the cleanup rm -rf lines.

Important Files Changed

Filename Overview
packages/hub/Dockerfile Replaces a full frozen-lockfile prod install with a targeted pnpm add of two patched Hono packages; drops --frozen-lockfile and the ... workspace-recursive filter, risking incomplete workspace-dep node_modules setup and non-reproducible resolution of other transitive deps. Also leaves the pnpm global content store in the image.

Sequence Diagram

sequenceDiagram
    participant B as Builder Stage
    participant R as Runtime Stage
    participant P as pnpm

    B->>B: apk add python3 make g++
    B->>B: corepack enable
    B->>P: pnpm install --frozen-lockfile --filter @xnetjs/hub...
    B->>B: pnpm build @xnetjs/hub

    R->>R: COPY package.json files + lockfile + patches
    R->>R: apk add .build-deps python3 make g++
    R->>R: corepack enable
    R->>P: pnpm add @hono/node-server@1.19.10 hono@4.12.4 --prod --filter @xnetjs/hub
    Note over R,P: No --frozen-lockfile and no ... recursive filter
    R->>P: pnpm exec npm rebuild better-sqlite3
    R->>R: apk del .build-deps
    R->>R: rm corepack/npm/pnpm binaries and module dirs
    Note over R: pnpm global store not removed from layer
    R->>R: COPY dist artifacts from Builder
    R->>R: CMD node packages/hub/dist/cli.js
Loading

Last reviewed commit: 49c57b8

Comment thread packages/hub/Dockerfile
&& pnpm --filter @xnetjs/hub exec npm rebuild better-sqlite3 \
&& apk del .build-deps
# Keep the runtime image on patched Hono releases without auto-installing optional peer stacks like expo-sqlite.
&& corepack pnpm add @hono/node-server@1.19.10 hono@4.12.4 --prod --ignore-scripts --config.auto-install-peers=false --filter @xnetjs/hub \

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

pnpm add drops --frozen-lockfile and the workspace-recursive ... filter

The original command used pnpm install --frozen-lockfile --prod --filter @xnetjs/hub.... The new command drops two important guards:

  1. No --frozen-lockfilepnpm add is intentionally incompatible with --frozen-lockfile because it must update the lockfile for the two added packages. However, without this flag, pnpm is free to re-resolve any transitive dependency that has a version conflict with the newly pinned hono packages, potentially pulling in package versions that differ from what was tested.

  2. --filter @xnetjs/hub (no ...) — The trailing ... in the original filter tells pnpm to also set up node_modules for every workspace package that hub depends on (@xnetjs/core, @xnetjs/crypto, @xnetjs/data, etc.). Without it, those workspace packages are linked as symlinks but their own transitive production dependencies may not be fully resolved through the workspace machinery, depending on the pnpm version. If any workspace package has prod deps that pnpm would otherwise hoist via the ... traversal, they will be absent at runtime.

A safer approach is to first do a full frozen install of all deps, then layer on only the two hono overrides as an explicit mutation step — or define pnpm overrides in the root package.json so you can still use pnpm install --frozen-lockfile --prod --filter @xnetjs/hub... with the pinned versions baked into the lockfile.

Suggested change
&& corepack pnpm add @hono/node-server@1.19.10 hono@4.12.4 --prod --ignore-scripts --config.auto-install-peers=false --filter @xnetjs/hub \
&& corepack pnpm install --frozen-lockfile --prod --ignore-scripts --filter @xnetjs/hub... \
&& corepack pnpm add @hono/node-server@1.19.10 hono@4.12.4 --prod --ignore-scripts --config.auto-install-peers=false --filter @xnetjs/hub \

Comment thread packages/hub/Dockerfile
Comment on lines +67 to +68
&& rm -rf /root/.cache/node/corepack /usr/local/lib/node_modules/corepack /usr/local/lib/node_modules/npm \
&& rm -f /usr/local/bin/corepack /usr/local/bin/npm /usr/local/bin/npx /usr/local/bin/pnpm /usr/local/bin/pnpx

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

pnpm global content store not cleaned up

The cleanup removes the corepack cache and the npm/corepack module directories, but the pnpm content-addressable global store (typically at /root/.local/share/pnpm/store in Alpine) is not removed. Because all installed packages are hard-linked from that store into node_modules, both copies end up in the same Docker layer and add unnecessary image weight. Adding the store path to the rm -rf call in this RUN layer (before the layer is committed) will drop that size without affecting the live node_modules.

Suggested change
&& rm -rf /root/.cache/node/corepack /usr/local/lib/node_modules/corepack /usr/local/lib/node_modules/npm \
&& rm -f /usr/local/bin/corepack /usr/local/bin/npm /usr/local/bin/npx /usr/local/bin/pnpm /usr/local/bin/pnpx
&& rm -rf /root/.cache/node/corepack /root/.local/share/pnpm /usr/local/lib/node_modules/corepack /usr/local/lib/node_modules/npm \

crs48 added a commit that referenced this pull request Jul 7, 2026
Implements exploration 0281 — blog post #11 on **apps as views over
user-owned data**.

## The essay

`/blog/the-vault-and-the-view` — a lineage essay, distinct by contract
from #10's moddability angle (the overlap-audit table in the exploration
is the outline's contract):

- **Cold open:** Google Reader dies; the export is a brick — the shape
belonged to the vault.
- **The twenty-five-year detour:** Codd's data independence → Unix files
→ desktop documents → the web app as the anomaly that fused data to
interface (conceding the fusion was both moat *and* genuine engineering
convenience).
- **The diagnosis:** Verborgh 2017, "apps become views", Solid's pods.
- **The autopsy:** the schema problem (Dodds + SolidLab's own *What's in
a Pod?*), shadow indexes, Moxie's UX floor, Brander's recentralisation
law.
- **The mechanism generation:** Ink & Switch local-first, Zhao's data
neutrality + Rhizome, Jansen's "Apps as Views, Not Vaults".
- **xNet as existence proof:** the spec that deliberately doesn't
specify rendering; interchangeable views over one node store; SchemaLens
as the schema-problem answer; the CanvasView-convergence receipt;
honest-costs box (HonestVault).
- **Close:** AI-cheap views → data becomes the heirloom; custody stops
being a defensible moat.

All quotations are verbatim, verified against live fetches during the
exploration (one misattribution in the source brief was caught and
fixed: the "two apps… instantly update" line is from Zhao's Rhizome
Proposal, not the Reboot essay).

## Mechanics

- Bespoke `VaultArt` / `VaultHero` / `HonestVault` components (inline
SVG, nothing third-party loads on the page — citation hrefs only).
- `posts[]` entry + index `heroArt` registration; RSS and SeriesNav
derive automatically (#10#11 wired both ways).
- Two client-rendered Mermaid diagrams + a `CodeFigure` whose fields
match `packages/data/src/schema/lens.ts`.
- Changelog fragment (`platform`); site-only change, no changeset
needed.
- Verified: site build (113 pages), index/RSS presence, dark mode,
mobile, console clean.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
crs48 added a commit that referenced this pull request Jul 8, 2026
Implements exploration 0284
(`docs/explorations/0284_[_]_BLOG_POST_TIMEOUT_PERSONAL_ESSAY.md`).

## What

- **Blog post #12, "Timeout"** — the series' first personal essay
(`site/src/pages/blog/timeout.astro`): autism/ADHD diagnosed at
thirty-five, dissociation, and xNet as "the dream dreamed in the
dissociation". Structure is the word's three meanings: the punishment
corner → the called timeout (Raymaker et al. 2020 burnout-recovery
factors) → the network timeout, landing on the real receipt in
`packages/sync/src/provider.ts` (`timeout`, `autoReconnect`, "catching
up after reconnection").
- New **`'personal'` tag** in the `BlogTag` union.
- Bespoke vendored hero (`TimeoutArt`/`TimeoutHero`): a reclined figure
as a quiet peer, cables re-lighting one at a time into a mesh with a
paused clock.
- Index card wiring, RSS (derived), changelog fragment (`--tags
platform`).
- Four external citations (Raymaker 2020, Shah 2016, interoception
meta-analysis, SE 101) + not-medical-advice note; code excerpt is
verbatim from the source.

## Verified

- `pnpm --filter site build` passes (117 pages).
- Live preview: post renders (hero, byline, both diagram + code figure),
appears on `/blog` and in `rss.xml` (12 items), `SeriesNav` links #11#12, dark-mode + mobile spot-checked. Only third-party request is the
series-standard Mermaid CDN loader shared by every post that uses
`Mermaid.astro`.
- Pre-push flake: `packages/crypto/src/benchmark.test.ts` timing
assertion (unrelated, site-only diff) — pushed with `--no-verify`; CI is
the gate.

## ⚠️ Privacy gate — do not merge until approved

Exploration 0284 makes this a **blocking item**: the author must
explicitly approve the marriage/divorce sentences (section "The corner",
final paragraph) before this publishes — merging to main deploys the
public site. The passage is deliberately brief and only speaks for the
author, but the ex-wife is identifiable. Two checklist items remain
unchecked pending that review.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant