refactor(ollama): migrate auth proxy to .mts - #6949
Conversation
Convert scripts/ollama-auth-proxy.js to a typed ESM .mts entrypoint running under Node native type stripping without tsx. Preserve the fail-closed Bearer-token check, byte-length gate before timingSafeEqual, authorization header stripping, loopback backend, and EADDRINUSE exit. Trim the process needle to ollama-auth-proxy so upgrade and recovery still detect the old .js process next to the new .mts. Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
📝 WalkthroughWalkthroughThe authenticated Ollama reverse proxy moves from the removed JavaScript entrypoint to a new TypeScript module. Process matching, lifecycle management, uninstall detection, restart helpers, and tests now use the ChangesOllama proxy migration
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related issues
Possibly related PRs
Suggested labels: Suggested reviewers: Sequence Diagram(s)sequenceDiagram
participant Client
participant OllamaAuthProxy
participant OllamaBackend
Client->>OllamaAuthProxy: Send request with Bearer token
OllamaAuthProxy->>OllamaBackend: Forward authorized request
OllamaBackend-->>OllamaAuthProxy: Return response
OllamaAuthProxy-->>Client: Return proxied response
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Code Coverage OverviewLanguages: TypeScript TypeScript / code-coverage/pluginThe overall coverage remains at 96%, unchanged from the TypeScript / code-coverage/cliThe overall coverage in the Show a code coverage summary of the most impacted files.
Updated |
PR Review Advisor — InformationalAdvisor assessment: Informational / high confidence Model lanes
Nemotron output stays in workflow artifacts and does not change the assessment above. E2E guidanceAdvisory only. E2E / PR Gate selects and runs jobs independently. Recommended E2E: This automated review informs maintainers. Warnings and suggestions do not require a response. A maintainer decides whether to merge. |
cv
left a comment
There was a problem hiding this comment.
Security review found one blocking process-ownership regression. The new bare ollama-auth-proxy marker is passed to cmdline.includes() in both proxy lifecycle cleanup and uninstall. That can misclassify and kill near-named processes such as ollama-auth-proxy-helper.mjs or ollama-auth-proxy.mts.backup; uninstall can amplify the impact when elevated. Please match only the legacy .js and new .mts filename tokens with path-boundary semantics, then add positive tests for both supported filenames and negative tests for helper/suffix near matches. The unflagged .mts execution is valid under the repository Node >=22.19 contract and is not a blocker.
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
# Conflicts: # src/lib/actions/uninstall/run-plan.ts # src/lib/inference/local-adapter-lifecycle.ts
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/lib/inference/ollama/process.ts (1)
4-8: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winRegex correctly matches both
.js/.mtsand excludes near-named scripts; add retirement tracking for the.jscompatibility branch.Verified against the test fixtures in
local-adapter-lifecycle.test.tsandrun-plan.test.ts:ollama-auth-proxy.js/ollama-auth-proxy.mtsmatch, whileollama-auth-proxy-helper.mjsandollama-auth-proxy.mts.backupcorrectly do not. This satisfies the stated requirement that existing.jsprocesses remain detectable during upgrades/uninstall.Per path instructions, retaining a superseded path is only sanctioned for "a demonstrated external/persisted-data contract or a bounded confidence/rollback window," and requires linking "the retirement issue or PR in GitHub" and stating "observable exit criteria." The
.jsbranch here is a legitimate compat window (detecting already-running old proxy processes on upgrade), but there's no comment linking a retirement issue or criteria for eventually dropping.jsdetection once it's no longer needed.As per path instructions: "Retain an old path only for a demonstrated external/persisted-data contract or a bounded confidence/rollback window... link the retirement issue or PR in GitHub, and state observable exit criteria."
📝 Suggested doc note
+// Retains detection of the legacy `.js` entrypoint so upgrades/uninstalls can +// clean up already-running pre-migration processes. Remove the `js` branch +// once no supported install can still be running the legacy script — track +// retirement in issue `#6926` (or a follow-up). const OLLAMA_AUTH_PROXY_SCRIPT_PATTERN = /(?:^|[\s/\\])ollama-auth-proxy\.(?:js|mts)(?=$|\s)/;🤖 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 `@src/lib/inference/ollama/process.ts` around lines 4 - 8, Add a concise maintenance comment near OLLAMA_AUTH_PROXY_SCRIPT_PATTERN documenting that .js detection is retained for upgrade/uninstall compatibility, linking the retirement issue or PR, and defining observable exit criteria for removing it. Keep the existing regex and isOllamaAuthProxyCommandLine behavior unchanged.Source: Path instructions
🤖 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.
Nitpick comments:
In `@src/lib/inference/ollama/process.ts`:
- Around line 4-8: Add a concise maintenance comment near
OLLAMA_AUTH_PROXY_SCRIPT_PATTERN documenting that .js detection is retained for
upgrade/uninstall compatibility, linking the retirement issue or PR, and
defining observable exit criteria for removing it. Keep the existing regex and
isOllamaAuthProxyCommandLine behavior unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 1b18de37-9105-432c-abc2-09fec8191b0c
📒 Files selected for processing (8)
src/lib/actions/uninstall/run-plan.test.tssrc/lib/actions/uninstall/run-plan.tssrc/lib/inference/bedrock-runtime-adapter.tssrc/lib/inference/local-adapter-lifecycle.test.tssrc/lib/inference/local-adapter-lifecycle.tssrc/lib/inference/ollama/process.tssrc/lib/inference/ollama/proxy.tssrc/lib/inference/openrouter-runtime-adapter-lifecycle.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- src/lib/inference/ollama/proxy.ts
Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com>
There was a problem hiding this comment.
🧹 Nitpick comments (1)
test/ollama-auth-proxy-handler.test.ts (1)
149-161: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winCheck stdout as well as stderr for token leakage.
The test pipes
child.stdoutbut only asserts that the token is absent from stderr. A regression usingconsole.log(TOKEN)would therefore pass. Capture stdout and assert the token is absent from both output streams.Proposed adjustment
+ const stdoutChunks: Buffer[] = []; + child.stdout?.on("data", (chunk) => stdoutChunks.push(Buffer.from(chunk))); const stderrChunks: Buffer[] = []; child.stderr?.on("data", (chunk) => stderrChunks.push(Buffer.from(chunk))); const [exitCode, signal] = (await once(child, "close")) as [number | null, string | null]; + const stdout = Buffer.concat(stdoutChunks).toString("utf8"); const stderr = Buffer.concat(stderrChunks).toString("utf8"); expect(signal).toBeNull(); expect(exitCode).not.toBe(0); expect(stderr).toContain(`Ollama auth proxy: port ${occupiedPort} is already in use`); + expect(stdout).not.toContain(TOKEN); expect(stderr).not.toContain(TOKEN);🤖 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 `@test/ollama-auth-proxy-handler.test.ts` around lines 149 - 161, Update the child-process output assertions around the existing stderr capture to also collect child.stdout, then convert it to text and assert TOKEN is absent from stdout as well as stderr. Preserve the current exit, signal, and stderr error-message assertions.
🤖 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.
Nitpick comments:
In `@test/ollama-auth-proxy-handler.test.ts`:
- Around line 149-161: Update the child-process output assertions around the
existing stderr capture to also collect child.stdout, then convert it to text
and assert TOKEN is absent from stdout as well as stderr. Preserve the current
exit, signal, and stderr error-message assertions.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 82065246-efdb-4a29-8a67-63f04a10597f
📒 Files selected for processing (2)
src/lib/inference/ollama/process.tstest/ollama-auth-proxy-handler.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- src/lib/inference/ollama/process.ts
Resolved by commit 3a4e4c6: filename-bounded matcher plus positive and negative near-name tests. Maintainer security re-review passed.
cv
left a comment
There was a problem hiding this comment.
Security blocker resolved in 3a4e4c6. The matcher is filename-bounded, both supported names and near-name exclusions are tested, canonical CI and CodeRabbit are green, and the focused security/correctness review passed. Protected E2E remains required before merge.
|
Superseded by #6974 after #6938 created a two-file merge conflict that this contributor branch could not accept maintainer updates for. #6974 preserves all verified commits from this PR, retains the security fix and tests, and records the mechanical resolution against current main. Thank you @laitingsheng and @prekshivy for the implementation and follow-up fixes. |
|
@cjagwani |
## Summary Migrate the host-side Ollama authentication proxy from CommonJS `scripts/ollama-auth-proxy.js` to the typed ESM `scripts/ollama-auth-proxy.mts` entrypoint while preserving the existing request-handling and lifecycle contract. This maintainer salvage preserves the verified commits from #6949 and reconciles its process matcher with the Bedrock adapter migration merged in #6938. ## Related Issue Resolves #6926 Part of #6918 Supersedes #6949 ## Changes - Rename the Ollama authentication proxy entrypoint to `.mts` and retain its fail-closed Bearer-token check, byte-length gate before `timingSafeEqual`, sensitive-header stripping, loopback backend, public listener, and nonzero `EADDRINUSE` behavior. - Match only filename-bounded legacy `.js` and current `.mts` proxy processes during lifecycle cleanup and uninstall, with positive coverage for both names and negative coverage for helper and suffix near matches. - Reconcile the shared local-adapter matcher after #6938: strings use substring matching, regular expressions retain Bedrock's bounded launcher matching, and callbacks support Ollama's ownership predicate. All call sites use the existing `processMatcher` name. - Repoint unit, recovery, uninstall, and live E2E fixtures to the `.mts` entrypoint. ## Type of Change - [x] Code change (feature, bug fix, or refactor) - [ ] Code change with doc updates - [ ] Doc only (prose changes, no code sample modifications) - [ ] Doc only (includes code sample changes) ## Quality Gates - [x] Tests added or updated for changed behavior - [ ] Existing tests cover changed behavior — justification: - [ ] Tests not applicable — justification: - [ ] Docs updated for user-facing behavior changes - [x] Docs not applicable — justification: the filenames and shared matcher are internal; existing setup, lifecycle, uninstall, and port-conflict documentation remains accurate. A documentation-writer review found no page or standalone changelog change necessary. - [x] Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging) - [x] Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: the focused security re-review on #6949 passed after the bounded matcher and negative tests were added; the conflict resolution preserves #6938's bounded Bedrock matcher and was independently revalidated. - [ ] Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue: ## Verification - [x] PR description includes a `Signed-off-by:` line and every commit appears as `Verified` in GitHub - [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or `npm run check:diff` passed when hooks were skipped or unavailable - [x] Targeted behavior tests pass for the current change set, or tests are marked not applicable above — 85 focused lifecycle, Bedrock, uninstall, handler, and recovery tests passed after generating ignored build artifacts. - [ ] Applicable broad gate passed — `npm test` for broad runtime/test-harness changes; `npm run check` for repo-wide validation/coverage changes — command/result: - [x] Quality Gates section completed with required justifications or waivers - [x] No secrets, API keys, or credentials committed - [ ] `npm run docs` builds without warnings (doc changes only) - [ ] Doc pages follow the [style guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md) (doc changes only) - [ ] New doc pages include SPDX header and frontmatter (new pages only) Additional validation: `npm run build:cli` and `npm run typecheck:cli` passed. All original #6949 commits remain in the branch unchanged, and the signed merge commit records the mechanical two-file resolution against current `main`. --- Signed-off-by: Tinson Lai <tinsonl@nvidia.com> Signed-off-by: Carlos Villela <cvillela@nvidia.com> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Updated the authenticated Ollama proxy launcher to the TypeScript module entrypoint with configurable ports. * **Bug Fixes** * Improved proxy and local-adapter process detection so cleanup targets only the intended auth-proxy variants. * Enhanced handling of proxy startup when the configured port is already in use, and better behavior during backend disconnects. * **Tests** * Expanded coverage for proxy ownership, restart/recovery flows, near-name process matching, and error cases (including port conflicts and backend disconnect scenarios). <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Signed-off-by: Tinson Lai <tinsonl@nvidia.com> Signed-off-by: Prekshi Vyas <prekshiv@nvidia.com> Signed-off-by: Carlos Villela <cvillela@nvidia.com> Co-authored-by: Tinson Lai <tinsonl@nvidia.com> Co-authored-by: Prekshi Vyas <prekshiv@nvidia.com>
Summary
Migrate the host-side Ollama authentication proxy from CommonJS
scripts/ollama-auth-proxy.jsto a typed ESMscripts/ollama-auth-proxy.mtsentrypoint that runs under Node native type stripping withouttsx. The request-handling and lifecycle contract is unchanged; only the entrypoint module format and the process-detection needle move.Related Issue
Resolves #6926
Part of #6918
Changes
scripts/ollama-auth-proxy.jstoscripts/ollama-auth-proxy.mts; convertrequiretonode:crypto/node:httpESM imports and add explicit request/response types. The security contract is preserved: fail-closed Bearer-token check, byte-length gate beforecrypto.timingSafeEqual,authorizationandhostheader stripping,127.0.0.1backend,0.0.0.0listener, and cleanEADDRINUSEexit.spawnOllamaAuthProxyat the.mtsentrypoint insrc/lib/inference/ollama/proxy.ts.ollama-auth-proxy.jstoollama-auth-proxyinsrc/lib/inference/ollama/proxy.tsandsrc/lib/actions/uninstall/run-plan.ts. Requirement: an already-installed proxy runs as.../ollama-auth-proxy.js, so upgrade and uninstall must still detect and stop it while new spawns use.mts. Consumers:isOllamaProxyProcessandkillStaleProxy(proxy.ts) andOLLAMA_AUTH_PROXY_CMDLINE_MARK(run-plan.ts). A direct pin to.mtswould leak a running.jsproxy on upgrade. Protected bytest/ollama-proxy-recovery.test.ts,test/ollama-proxy-startup.test.ts, andsrc/lib/actions/uninstall/run-plan.test.ts..mtspath in the unit harness and the live E2E target (test/ollama-auth-proxy-handler-helpers.ts,test/ollama-proxy-recovery.test.ts,test/e2e/live/gpu-e2e-helpers.ts,test/e2e/live/ollama-auth-proxy.test.ts) and the handler-test doc comment.Type of Change
Quality Gates
EADDRINUSE, and old-process upgrade-detection contract is already pinned bytest/ollama-auth-proxy-handler.test.ts,test/ollama-proxy-recovery.test.ts,test/ollama-proxy-startup.test.ts,src/lib/inference/local-adapter-lifecycle.test.ts, andsrc/lib/actions/uninstall/run-plan.test.ts; the migration repoints paths and the needle without changing the contract, and these suites stay green (71 tests)..jsproxy (only the module format and the extensionless needle change); awaiting maintainer sensitive-path review.Verification
Signed-off-by:line and every commit appears asVerifiedin GitHubpre-commit,commit-msg, andpre-pushhooks passed, ornpm run check:diffpassed when hooks were skipped or unavailablenpx vitest runon the five focused suites → 71 passed;npm run typecheck:cli→ pass (both on the merged base under Node 22.22).npm testfor broad runtime/test-harness changes;npm run checkfor repo-wide validation/coverage changes — command/result:npm run docsbuilds without warnings (doc changes only)Signed-off-by: Tinson Lai tinsonl@nvidia.com
Summary by CodeRabbit