Skip to content

fix(security): verify SHA-256 checksum on OpenShell binary download#697

Merged
ericksoa merged 5 commits intomainfrom
fix/openshell-checksum-verify
Mar 30, 2026
Merged

fix(security): verify SHA-256 checksum on OpenShell binary download#697
ericksoa merged 5 commits intomainfrom
fix/openshell-checksum-verify

Conversation

@ericksoa
Copy link
Copy Markdown
Contributor

@ericksoa ericksoa commented Mar 23, 2026

Summary

scripts/install-openshell.sh downloads the OpenShell binary via curl/gh and installs it (often as root) without any integrity verification. OpenShell releases include openshell-checksums-sha256.txt alongside the tarballs — verified present in v0.0.10 through v0.0.13.

Signed-off-by: Aaron Erickson aerickson@nvidia.com

Changes

  • Download openshell-checksums-sha256.txt alongside the tarball (both gh and curl paths)
  • Verify via shasum -a 256 -c before extraction
  • Fail with a clear error message if verification fails
  • Use grep -F for fixed-string matching (review feedback from @cv)

Type of Change

  • Code change for a new feature, bug fix, or refactor.

Testing

  • npx prek run --all-files passes (or equivalently make check).
  • npm test passes (649/649).
  • Verified checksum file exists in all recent OpenShell releases (v0.0.10–v0.0.13)
  • Manual: nemoclaw onboard installs OpenShell with checksum verification
  • Manual: tamper with downloaded tarball → verify installation fails with clear error

Checklist

General

Code Changes

  • Formatters applied — npx prek run --all-files auto-fixes formatting.
  • Tests added or updated for new or changed behavior.
  • No secrets, API keys, or credentials committed.

Summary by CodeRabbit

Chores

  • Installation script now downloads verification checksums alongside archives and validates all downloads using SHA-256 before extracting files. Installation fails safely if validation fails.

Tests

  • Added regression test to verify SHA-256 checksum validation remains integrated in the installation process.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 23, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1083471c-ca4f-453b-a21c-3f209de9b036

📥 Commits

Reviewing files that changed from the base of the PR and between 1c9038c and 2f34212.

📒 Files selected for processing (2)
  • scripts/install-openshell.sh
  • test/runner.test.js
✅ Files skipped from review due to trivial changes (1)
  • test/runner.test.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • scripts/install-openshell.sh

📝 Walkthrough

Walkthrough

The install script for OpenShell now includes SHA-256 checksum verification. It downloads a checksums file, validates the downloaded archive against it, and only proceeds with extraction upon successful verification. A regression test ensures these safety checks remain present in the script.

Changes

Cohort / File(s) Summary
Checksum Verification Implementation
scripts/install-openshell.sh
Added download of openshell-checksums-sha256.txt, SHA-256 validation of the archive using shasum -a 256 -c, and script termination on verification failure. Archive extraction now occurs only after successful validation.
Regression Test
test/runner.test.js
Added synchronous regression test in "regression guards" suite that verifies the install script references the checksums file and includes the SHA-256 checksum verification command.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~4 minutes

Poem

🐰 A checksum here, a hash so true,
SHA-256 makes the downloads new,
No corrupted files shall pass our gate,
The shells now safe—oh, how we celebrate! ✨

🚥 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 accurately summarizes the main change: adding SHA-256 checksum verification for OpenShell binary downloads, which is the primary security improvement across both install scripts.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/openshell-checksum-verify

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (3)
scripts/install-openshell.sh (2)

82-98: Checksum verification correctly implemented with proper cleanup.

This script has the EXIT trap at line 80, ensuring $tmpdir is cleaned up regardless of success or failure. The checksum verification logic is consistent with scripts/install.sh.

Same minor note about grep precision applies here:

♻️ Optional: Use fixed-string grep for precision
-  (cd "$tmpdir" && grep "$ASSET" "$CHECKSUM_FILE" | shasum -a 256 -c -) \
+  (cd "$tmpdir" && grep -F "$ASSET" "$CHECKSUM_FILE" | shasum -a 256 -c -) \
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/install-openshell.sh` around lines 82 - 98, The checksum verification
uses grep "$ASSET" "$CHECKSUM_FILE" which can mis-match substrings; update the
verification command to use a fixed-string or exact-match grep (e.g., use grep
-F or grep -x) so CHECKSUM_FILE is searched precisely for the ASSET entry before
piping to shasum -a 256 -c -; modify the line that runs (cd "$tmpdir" && grep
"$ASSET" "$CHECKSUM_FILE" | shasum -a 256 -c -) to reference the chosen grep
option and ensure variables GH_TOKEN, ASSET, CHECKSUM_FILE and tmpdir remain
unchanged.

96-97: Consider handling missing checksum entry explicitly.

If grep "$ASSET" finds no match (asset not listed in checksum file), the pipeline will fail with "SHA-256 checksum verification failed." This is technically correct, but the error message could be misleading—the failure isn't a mismatch but a missing entry.

♻️ Optional: More informative error handling
 info "Verifying SHA-256 checksum..."
-(cd "$tmpdir" && grep "$ASSET" "$CHECKSUM_FILE" | shasum -a 256 -c -) \
-  || fail "SHA-256 checksum verification failed for $ASSET"
+(cd "$tmpdir" && {
+  checksum_line=$(grep -F "$ASSET" "$CHECKSUM_FILE") \
+    || fail "Asset $ASSET not found in $CHECKSUM_FILE"
+  echo "$checksum_line" | shasum -a 256 -c -
+}) || fail "SHA-256 checksum verification failed for $ASSET"

This is optional since the current behavior is safe (fails closed), just less descriptive.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/install-openshell.sh` around lines 96 - 97, The failure message is
ambiguous when the checksum file lacks an entry for ASSET; before piping into
shasum, test for a matching line in CHECKSUM_FILE (e.g., use grep -q -- "$ASSET"
"$CHECKSUM_FILE" or capture the grep output into a variable), and if no match
call fail with a clear message like "No checksum entry for $ASSET in
$CHECKSUM_FILE"; otherwise feed the matching line to shasum -a 256 -c - and keep
the existing failure path for actual checksum mismatches.
scripts/install.sh (1)

339-356: Good security improvement with checksum verification.

The implementation correctly downloads and verifies the SHA-256 checksum before extraction. A few observations:

  1. Missing tmpdir cleanup on failure: Unlike install-openshell.sh which has trap 'rm -rf "$tmpdir"' EXIT (line 80), this script does not set up a trap. If checksum verification fails, $tmpdir is left behind.

  2. Grep pattern could be more precise: grep "$ASSET" could match multiple lines if a filename is a substring of another (e.g., openshell-x86_64 matching both openshell-x86_64-apple-darwin.tar.gz and a hypothetical openshell-x86_64-v2-apple-darwin.tar.gz). Consider anchoring the pattern.

♻️ Suggested improvements
   tmpdir="$(mktemp -d)"
+  trap 'rm -rf "$tmpdir"' EXIT
   CHECKSUM_FILE="openshell-checksums-sha256.txt"

For more precise grep matching (optional):

-  (cd "$tmpdir" && grep "$ASSET" "$CHECKSUM_FILE" | shasum -a 256 -c -) \
+  (cd "$tmpdir" && grep -F "$ASSET" "$CHECKSUM_FILE" | shasum -a 256 -c -) \

Using -F treats the pattern as a fixed string rather than a regex, which is safer and slightly faster.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/install.sh` around lines 339 - 356, The script currently downloads
checksums into $tmpdir but doesn't register a cleanup trap (leaving tmpdir if
verification fails) and uses grep "$ASSET" which can match substrings; add a
trap like the one in install-openshell.sh (trap 'rm -rf "$tmpdir"' EXIT)
immediately after creating tmpdir to ensure removal on exit/failure, and make
the verification grep precise by using fixed/anchored matching (e.g., use grep
-F or anchor the pattern to the exact filename when reading CHECKSUM_FILE) in
the (cd "$tmpdir" && grep ... "$CHECKSUM_FILE" | shasum -a 256 -c -) step so
only the exact ASSET entry is checked.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@scripts/install-openshell.sh`:
- Around line 82-98: The checksum verification uses grep "$ASSET"
"$CHECKSUM_FILE" which can mis-match substrings; update the verification command
to use a fixed-string or exact-match grep (e.g., use grep -F or grep -x) so
CHECKSUM_FILE is searched precisely for the ASSET entry before piping to shasum
-a 256 -c -; modify the line that runs (cd "$tmpdir" && grep "$ASSET"
"$CHECKSUM_FILE" | shasum -a 256 -c -) to reference the chosen grep option and
ensure variables GH_TOKEN, ASSET, CHECKSUM_FILE and tmpdir remain unchanged.
- Around line 96-97: The failure message is ambiguous when the checksum file
lacks an entry for ASSET; before piping into shasum, test for a matching line in
CHECKSUM_FILE (e.g., use grep -q -- "$ASSET" "$CHECKSUM_FILE" or capture the
grep output into a variable), and if no match call fail with a clear message
like "No checksum entry for $ASSET in $CHECKSUM_FILE"; otherwise feed the
matching line to shasum -a 256 -c - and keep the existing failure path for
actual checksum mismatches.

In `@scripts/install.sh`:
- Around line 339-356: The script currently downloads checksums into $tmpdir but
doesn't register a cleanup trap (leaving tmpdir if verification fails) and uses
grep "$ASSET" which can match substrings; add a trap like the one in
install-openshell.sh (trap 'rm -rf "$tmpdir"' EXIT) immediately after creating
tmpdir to ensure removal on exit/failure, and make the verification grep precise
by using fixed/anchored matching (e.g., use grep -F or anchor the pattern to the
exact filename when reading CHECKSUM_FILE) in the (cd "$tmpdir" && grep ...
"$CHECKSUM_FILE" | shasum -a 256 -c -) step so only the exact ASSET entry is
checked.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: aed8a69f-7e86-4cd5-94b6-bd88862a8fe3

📥 Commits

Reviewing files that changed from the base of the PR and between c55a309 and 4233787.

📒 Files selected for processing (3)
  • scripts/install-openshell.sh
  • scripts/install.sh
  • test/runner.test.js

@ericksoa ericksoa self-assigned this Mar 23, 2026
@cv cv force-pushed the fix/openshell-checksum-verify branch from 4233787 to 223e46e Compare March 23, 2026 20:46
@wscurran wscurran added enhancement New feature or request OpenShell Support for OpenShell, a safe, private runtime for autonomous AI agents security Something isn't secure labels Mar 23, 2026
Copy link
Copy Markdown
Contributor

@cv cv left a comment

Choose a reason for hiding this comment

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

The checksum verification works for detecting transport corruption (truncated downloads, bit flips). However, both the binary and openshell-checksums-sha256.txt are fetched from the same GitHub release — an attacker who can compromise the release artifacts can replace both. This doesn't protect against the supply chain threat that fix(security) implies.

Filed upstream: NVIDIA/OpenShell#542 requests artifact attestations, which would provide cryptographic provenance verification.

Two items before merge:

  1. install.sh is missing a trap 'rm -rf "$tmpdir"' EXITinstall-openshell.sh has one (line 80), but install.sh does not. On checksum failure, the downloaded binary persists on disk.
  2. Consider grep -F instead of grep for the checksum lookup — $ASSET contains dots and hyphens that are regex metacharacters.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
scripts/install.sh (1)

358-360: Use exact field matching for checksum file lookup.

At line 359, grep "$ASSET" matches by regex/substring. For more robust checksum verification, match the exact filename field and verify exactly one entry exists.

Proposed patch
   info "Verifying SHA-256 checksum..."
-  (cd "$tmpdir" && grep "$ASSET" "$CHECKSUM_FILE" | shasum -a 256 -c -) \
+  (cd "$tmpdir" && \
+    awk -v asset="$ASSET" '
+      $2 == asset { print; count++ }
+      END { exit(count == 1 ? 0 : 1) }
+    ' "$CHECKSUM_FILE" | shasum -a 256 -c -) \
     || fail "SHA-256 checksum verification failed for $ASSET"

This ensures the checksum file lookup matches the exact filename field rather than substring matching, preventing potential ambiguity if similarly named assets are added in the future.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/install.sh` around lines 358 - 360, The checksum lookup currently
uses grep "$ASSET" which can match substrings; instead, in the block that runs
in (cd "$tmpdir" && ... | shasum -a 256 -c -) use a strict field match against
the filename (ASSET) in CHECKSUM_FILE and verify exactly one matching line is
returned before piping to shasum. Concretely, replace the grep step with a
precise extractor (e.g., awk or grep -F with field anchoring) that matches the
filename field equal to the ASSET variable, count matches and fail if not
exactly one, then pass that single line to shasum -a 256 -c -. Keep references
to tmpdir, ASSET and CHECKSUM_FILE when locating code to change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@scripts/install.sh`:
- Around line 358-360: The checksum lookup currently uses grep "$ASSET" which
can match substrings; instead, in the block that runs in (cd "$tmpdir" && ... |
shasum -a 256 -c -) use a strict field match against the filename (ASSET) in
CHECKSUM_FILE and verify exactly one matching line is returned before piping to
shasum. Concretely, replace the grep step with a precise extractor (e.g., awk or
grep -F with field anchoring) that matches the filename field equal to the ASSET
variable, count matches and fail if not exactly one, then pass that single line
to shasum -a 256 -c -. Keep references to tmpdir, ASSET and CHECKSUM_FILE when
locating code to change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9d2bfc6e-5547-4eb2-a3d4-80ccfa89a488

📥 Commits

Reviewing files that changed from the base of the PR and between 4233787 and 223e46e.

📒 Files selected for processing (3)
  • scripts/install-openshell.sh
  • scripts/install.sh
  • test/runner.test.js
🚧 Files skipped from review as they are similar to previous changes (2)
  • scripts/install-openshell.sh
  • test/runner.test.js

Copy link
Copy Markdown
Contributor

@fdzdev fdzdev left a comment

Choose a reason for hiding this comment

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

Looks good. Checksum is verified before extraction in both the gh and curl
paths, and set -e ensures a missing checksum file fails the script early
(fail-closed). Regression tests cover both install scripts.

One minor note: if NVIDIA/OpenShell ever ships a release without
openshell-checksums-sha256.txt, the install will hard-fail. That's the
right behavior, but worth a note in the release checklist upstream.

cv and others added 3 commits March 25, 2026 07:46
- Use grep -F for fixed-string matching in install-openshell.sh (ASSET
  contains dots/hyphens that are regex metacharacters)
- Remove stale install.sh checksum test (scripts/install.sh is now a
  thin legacy wrapper that delegates to root install.sh)
@ericksoa
Copy link
Copy Markdown
Contributor Author

Both items addressed:

  1. scripts/install.sh was refactored on main into a thin legacy wrapper that delegates to the root install.sh — it no longer downloads OpenShell or creates a tmpdir, so the missing trap is moot. The only script that downloads OpenShell is scripts/install-openshell.sh, which already has the trap (line 80).
  2. Switched to grep -F in install-openshell.sh.

Also removed the stale regression test that checked scripts/install.sh for checksum strings, since that file no longer contains install logic.

@ericksoa ericksoa merged commit c8a82f6 into main Mar 30, 2026
13 of 14 checks passed
laitingsheng pushed a commit that referenced this pull request Apr 2, 2026
…697)

## Summary

`scripts/install-openshell.sh` downloads the OpenShell binary via
`curl`/`gh` and installs it (often as root) without any integrity
verification. OpenShell releases include
`openshell-checksums-sha256.txt` alongside the tarballs — verified
present in v0.0.10 through v0.0.13.

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>

## Changes

- Download `openshell-checksums-sha256.txt` alongside the tarball (both
`gh` and `curl` paths)
- Verify via `shasum -a 256 -c` before extraction
- Fail with a clear error message if verification fails
- Use `grep -F` for fixed-string matching (review feedback from @cv)

## Type of Change
- [x] Code change for a new feature, bug fix, or refactor.

## Testing

- [x] `npx prek run --all-files` passes (or equivalently `make check`).
- [x] `npm test` passes (649/649).
- [x] Verified checksum file exists in all recent OpenShell releases
(v0.0.10–v0.0.13)
- [ ] Manual: `nemoclaw onboard` installs OpenShell with checksum
verification
- [ ] Manual: tamper with downloaded tarball → verify installation fails
with clear error

## Checklist

### General
- [x] I have read and followed the [contributing
guide](https://github.com/NVIDIA/NemoClaw/blob/main/CONTRIBUTING.md).

### Code Changes
- [x] Formatters applied — `npx prek run --all-files` auto-fixes
formatting.
- [x] Tests added or updated for new or changed behavior.
- [x] No secrets, API keys, or credentials committed.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

**Chores**
* Installation script now downloads verification checksums alongside
archives and validates all downloads using SHA-256 before extracting
files. Installation fails safely if validation fails.

**Tests**
* Added regression test to verify SHA-256 checksum validation remains
integrated in the installation process.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Carlos Villela <cvillela@nvidia.com>
lakamsani pushed a commit to lakamsani/NemoClaw that referenced this pull request Apr 4, 2026
…VIDIA#697)

## Summary

`scripts/install-openshell.sh` downloads the OpenShell binary via
`curl`/`gh` and installs it (often as root) without any integrity
verification. OpenShell releases include
`openshell-checksums-sha256.txt` alongside the tarballs — verified
present in v0.0.10 through v0.0.13.

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>

## Changes

- Download `openshell-checksums-sha256.txt` alongside the tarball (both
`gh` and `curl` paths)
- Verify via `shasum -a 256 -c` before extraction
- Fail with a clear error message if verification fails
- Use `grep -F` for fixed-string matching (review feedback from @cv)

## Type of Change
- [x] Code change for a new feature, bug fix, or refactor.

## Testing

- [x] `npx prek run --all-files` passes (or equivalently `make check`).
- [x] `npm test` passes (649/649).
- [x] Verified checksum file exists in all recent OpenShell releases
(v0.0.10–v0.0.13)
- [ ] Manual: `nemoclaw onboard` installs OpenShell with checksum
verification
- [ ] Manual: tamper with downloaded tarball → verify installation fails
with clear error

## Checklist

### General
- [x] I have read and followed the [contributing
guide](https://github.com/NVIDIA/NemoClaw/blob/main/CONTRIBUTING.md).

### Code Changes
- [x] Formatters applied — `npx prek run --all-files` auto-fixes
formatting.
- [x] Tests added or updated for new or changed behavior.
- [x] No secrets, API keys, or credentials committed.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

**Chores**
* Installation script now downloads verification checksums alongside
archives and validates all downloads using SHA-256 before extracting
files. Installation fails safely if validation fails.

**Tests**
* Added regression test to verify SHA-256 checksum validation remains
integrated in the installation process.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Carlos Villela <cvillela@nvidia.com>
gemini2026 pushed a commit to gemini2026/NemoClaw that referenced this pull request Apr 14, 2026
…VIDIA#697)

## Summary

`scripts/install-openshell.sh` downloads the OpenShell binary via
`curl`/`gh` and installs it (often as root) without any integrity
verification. OpenShell releases include
`openshell-checksums-sha256.txt` alongside the tarballs — verified
present in v0.0.10 through v0.0.13.

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>

## Changes

- Download `openshell-checksums-sha256.txt` alongside the tarball (both
`gh` and `curl` paths)
- Verify via `shasum -a 256 -c` before extraction
- Fail with a clear error message if verification fails
- Use `grep -F` for fixed-string matching (review feedback from @cv)

## Type of Change
- [x] Code change for a new feature, bug fix, or refactor.

## Testing

- [x] `npx prek run --all-files` passes (or equivalently `make check`).
- [x] `npm test` passes (649/649).
- [x] Verified checksum file exists in all recent OpenShell releases
(v0.0.10–v0.0.13)
- [ ] Manual: `nemoclaw onboard` installs OpenShell with checksum
verification
- [ ] Manual: tamper with downloaded tarball → verify installation fails
with clear error

## Checklist

### General
- [x] I have read and followed the [contributing
guide](https://github.com/NVIDIA/NemoClaw/blob/main/CONTRIBUTING.md).

### Code Changes
- [x] Formatters applied — `npx prek run --all-files` auto-fixes
formatting.
- [x] Tests added or updated for new or changed behavior.
- [x] No secrets, API keys, or credentials committed.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

**Chores**
* Installation script now downloads verification checksums alongside
archives and validates all downloads using SHA-256 before extracting
files. Installation fails safely if validation fails.

**Tests**
* Added regression test to verify SHA-256 checksum validation remains
integrated in the installation process.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Carlos Villela <cvillela@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request OpenShell Support for OpenShell, a safe, private runtime for autonomous AI agents security Something isn't secure

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants