Skip to content

finding: crypto mode is selected from the VITEST runner variable in product code, so a spawned server can inherit test posture #11352

Description

@os-zhuang

Filed unassigned for triage grading. Deliberately not graded here — this seat is domain:cli and the file is packages/services/**.

packages/services/service-settings/src/local-crypto-provider.ts:133 selects crypto mode from the environment:

constdetectMode=(env: EnvMap): CryptoMode=>{if(env.VITEST||env.NODE_ENV==='test')return'test';if(env.NODE_ENV==='production')return'production';return'development';};

Reading VITEST for in-process unit tests is documented as intentional, and that is not what this records. What this records is that the variable is inherited by spawned server processes, so an os serve boot that merely happens to have VITEST in its environment silently takes an ephemeral key, no disk persistence, and — the part that matters — no refusal to boot without a stable key. The refusal is the gate.

How it was measured

Incidentally, while landing #11267 (PR #11340), which strips the vitest worker variables from spawned children. Before that strip, packages/cli/test/serve-node-env-production-default.e2e.test.ts — a pin whose entire subject is "unset NODE_ENV means production" — was running with auth in production posture and crypto in test posture, because the fixture inherited VITEST. Closing the leak is what made the inconsistency visible; it was undetectable while the leak was open.

Why it is not folded into #11267

That card's diff is 100% packages/cli/test/**. This is product code in another lane, and changing how a security gate selects its posture is not a test-harness repair.

Why this seat does not grade it

The in-process behaviour is intentional by design, so the real question is whether a spawned process inheriting that intent is in scope of it. That is a security-posture judgement — which key material a production boot receives, and whether it may boot at all without one — and per the manual-floor rule this seat neither grades nor adjudicates it.

Adjacent: #11341 covers the harness half (nothing mechanically stops the next packages/cli/test spawner from re-introducing a bare ...process.env child env).

Routing note for triage: the file lands in packages/services/service-settings/**.

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions