Skip to content

fix: Harden CLI distribution and Unity IPC security#1794

Merged
hatayama merged 5 commits into
v3-betafrom
security/cli-distribution-hardening-integration
Jul 15, 2026
Merged

fix: Harden CLI distribution and Unity IPC security#1794
hatayama merged 5 commits into
v3-betafrom
security/cli-distribution-hardening-integration

Conversation

@hatayama

@hatayama hatayama commented Jul 15, 2026

Copy link
Copy Markdown
Owner

Summary

This integration hardens CLI distribution, first installation, security scanning, and Unity IPC before release to v3-beta.

Finding 1: Bootstrap provenance (PR-2)

Previous behavior

The CLI-only and Unity installation paths could rely on same-origin checksums or mutable branch installer URLs, and the installer archive attestation manifest was optional.

Root cause

Integrity checks were not an authenticated trust root, and bootstrap inputs were not bound to one immutable dispatcher release and its verified subjects.

Fix

The package stores a CI-verified dispatcher release tag and canonical archive manifest in the pin. CLI-only bootstrap obtains the installer and its Sigstore bundle from that immutable release, derives the archive manifest from the verified bundle, and fails closed when verification material is absent or invalid. The installer verifies the archive and bundle before extraction or execution. Mutable curl | sh / irm | iex paths and checksum-only authentication are removed.

Attack conditions addressed

A substituted installer, archive, release tag, source identity, subject digest, malformed bundle, missing verifier input, or unavailable GitHub API cannot reach script or binary execution.

Test evidence

Pin reader/stamp/guard tests, installer manifest tests, workflow static tests, bootstrap bundle fixture, and exact-head CI are green. See PR #1791.

Residual risk

First installation requires network access and a GitHub CLI for the CLI-only path; offline bootstrap is unsupported. The package-local Unity path uses the CI-stamped SHA-256 manifest and does not require external gh.

Finding 2: Fail-closed C# security scanning (PR-3)

Previous behavior

The security workflow could create or accept placeholder SARIF and did not reliably distinguish scanner failure, unusable analysis, or missing SARIF from a clean scan.

Root cause

Scanner execution, SARIF validation, quality checks, and upload were not enforced as one fail-closed sequence.

Fix

Pinned CodeQL build-mode: none security-extended analysis now requires a real non-empty SARIF result. A Go guard validates SARIF schema, run count, tool identity, scanner status, and database quality floors; only verified SARIF reaches upload. C# quality floors are 55% call targets and 70% known types, with the 68%/82% PoC values exposed as non-blocking drift warnings.

Attack conditions addressed

An attacker cannot turn scanner failure, compile/database degradation, missing output, malformed SARIF, or a false zero-finding result into a green security check.

Test evidence

Probe and failure regression tests, workflow static tests, scripts/check-security-scan-workflow.sh, scripts/check-go-cli.sh, CodeQL SARIF validation, and exact-head CI are green. See PR #1792.

Residual risk

The approved corpus is Packages/src plus Assets/Tests; repo-wide C# coverage and Unity-generated project reference precision remain future work requiring remeasurement and owner reapproval.

Finding 3: Unix IPC user isolation and protocol generation 4 (PR-4)

Previous behavior

Unix IPC used a shared temporary endpoint boundary without sufficient owner, mode, symlink, and socket cleanup guarantees. Project resolution also validated the endpoint, breaking no-dial dispatcher commands when Unity had not created its directory.

Root cause

Endpoint protection was not consistently placed at the protected network operation, and the IPC rendezvous change required an explicit contract generation bump.

Fix

Both Unity and Go use /tmp/uloop-<effective UID>. The parent is checked through symlink resolution for root ownership and sticky mode; the endpoint directory is checked without following links for current-user ownership and exact 0700; sockets are restricted to 0600. Validation is performed at one client dial choke point, while project/pin/cache/help/version resolution remains usable without a running Unity endpoint. A restriction failure calls Stop() so a bound socket is closed and removed. The IPC protocol pair is bumped from 3 to 4 in one commit.

Attack conditions addressed

Other OS users cannot precreate, replace, or redirect the endpoint directory/socket to intercept or deny another user’s IPC. Untrusted replacement paths are never deleted, and failed validation never reaches a network dial.

Test evidence

Red-to-Green socket-cleanup regression, Unity compile with 0 errors/0 warnings, focused EditMode tests, Go tests/lint/vet/build, Windows/Linux cross-compilation, release trigger and dispatcher pin guards, and exact-head CI are green. See PR #1793.

Residual risk

A process running as the same OS user remains within the trust boundary. Protocol 4 requires release ordering before the package pin can advance.

PR-5 decision

Repository owner decision on 2026-07-15 cancels To-Do 25–28. This individual OSS project will not purchase Apple Developer, Authenticode, or Trusted Signing infrastructure. Free Sigstore attestation already covers every release asset, including beta releases; OS-native signing remains optional defense-in-depth and is not a prerequisite. No signing credentials or signing workflow changes are included.

Release ordering

Protocol 4 must be advertised by a project runner release first. Release-please then advances the project runner pin, followed by the Unity package release. check-protocol-minimum-version is expected to remain red for the interval before the runner release and pin advance; manually dispatched workflows without a PR diff skip that diff-dependent check.

Verification

  • Integration head: 06fcced00e5038d7dcf09588b08bdfc453c02f19
  • Build and Test run 29416123182 — success
  • Security Scan run 29416124911 — success
  • Local release, installer, attestation, workflow, pin, and bootstrap fixture tests — green
  • scripts/check-go-cli.sh and scripts/build-go-cli.sh — green
  • Unity compile — 0 errors, 0 warnings
  • Unity IPC EditMode — 11 passed, 3 expected Windows-only skipped
  • NativeCliInstaller/CliPinReader EditMode — 42 passed
  • Production publishing was not performed

Review in cubic

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@hatayama, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 8 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a0bd5e8e-9651-45a0-90a9-6d9fb0ac1c12

📥 Commits

Reviewing files that changed from the base of the PR and between dad66b7 and 06fcced.

⛔ Files ignored due to path filters (8)
  • Assets/Tests/Editor/UnixEndpointSecurityTests.cs.meta is excluded by none and included by none
  • Packages/src/Editor/Infrastructure/UnixEndpointSecurity.cs.meta is excluded by none and included by none
  • Packages/src/Editor/Infrastructure/UnixNativeFileSystem.cs.meta is excluded by none and included by none
  • cli/dispatcher/attestation/testdata/happy_asset_digest.txt is excluded by none and included by none
  • cli/dispatcher/attestation/testdata/happy_commit_sha.txt is excluded by none and included by none
  • cli/release-automation/go.mod is excluded by none and included by none
  • cli/release-automation/go.sum is excluded by !**/*.sum and included by none
  • scripts/install.ps1 is excluded by none and included by none
📒 Files selected for processing (88)
  • .github/workflows/build-and-test.yml
  • .github/workflows/dispatcher-publish.yml
  • .github/workflows/native-cli-publish.yml
  • .github/workflows/security-scan.yml
  • .uloop/project-runner-pin.json
  • Assets/Tests/Editor/BridgeTransportEndpointTests.cs
  • Assets/Tests/Editor/BridgeTransportListenerTests.cs
  • Assets/Tests/Editor/CliPathSetupFlowTests.cs
  • Assets/Tests/Editor/CliPinReaderServiceTests.cs
  • Assets/Tests/Editor/CliSetupApplicationServiceTests.cs
  • Assets/Tests/Editor/NativeCliInstallerTests.cs
  • Assets/Tests/Editor/UnixEndpointSecurityTests.cs
  • Packages/src/Editor/Application/CliPinReader.cs
  • Packages/src/Editor/Application/CliSetupApplicationService.cs
  • Packages/src/Editor/Domain/CliConstants.cs
  • Packages/src/Editor/Infrastructure/BridgeTransportEndpoint.cs
  • Packages/src/Editor/Infrastructure/BridgeTransportListener.cs
  • Packages/src/Editor/Infrastructure/CLI/CliPinReaderService.cs
  • Packages/src/Editor/Infrastructure/CLI/NativeCliCommandBuilder.cs
  • Packages/src/Editor/Infrastructure/CLI/NativeCliInstaller.cs
  • Packages/src/Editor/Infrastructure/UnixEndpointSecurity.cs
  • Packages/src/Editor/Infrastructure/UnixNativeFileSystem.cs
  • Packages/src/Editor/Presentation/Setup/SetupWizardCliWorkflowController.cs
  • Packages/src/Editor/Presentation/UnityCliLoopSettingsCliSetupPresenter.cs
  • Packages/src/project-runner-pin.json
  • README.md
  • README_ja.md
  • SECURITY.md
  • cli/common/clicontract/contract.json
  • cli/common/errors/error_envelope_classification.go
  • cli/common/errors/unity_endpoint_not_created.go
  • cli/common/errors/unity_endpoint_not_created_test.go
  • cli/common/ipcendpoint/unity_endpoint_not_created.go
  • cli/common/ipcendpoint/unix_endpoint_security.go
  • cli/common/ipcendpoint/unix_endpoint_security_test.go
  • cli/common/ipcendpoint/unix_endpoint_security_unix_test.go
  • cli/common/project/endpoint_contract_test.go
  • cli/common/project/project.go
  • cli/common/project/project_test.go
  • cli/common/unityipc/dial.go
  • cli/common/unityipc/dial_test.go
  • cli/common/unityipc/dial_unix.go
  • cli/common/unityipc/dial_windows.go
  • cli/common/unityipc/unix_endpoint_security_unix.go
  • cli/common/unityipc/unix_endpoint_security_windows.go
  • cli/dispatcher/attestation/errors.go
  • cli/dispatcher/attestation/fetcher.go
  • cli/dispatcher/attestation/policy.go
  • cli/dispatcher/attestation/policy_test.go
  • cli/dispatcher/attestation/testdata/happy_bundle.json
  • cli/dispatcher/attestation/trusted_root.go
  • cli/dispatcher/attestation/trusted_root.json
  • cli/dispatcher/attestation/trusted_root_test.go
  • cli/dispatcher/attestation/verifier.go
  • cli/dispatcher/attestation/verifier_test.go
  • cli/dispatcher/cmd/refresh-attestation-trusted-root/main.go
  • cli/dispatcher/internal/dispatcher/attestation_release.go
  • cli/dispatcher/internal/dispatcher/attestation_verify.go
  • cli/dispatcher/internal/dispatcher/attestation_verify_test.go
  • cli/dispatcher/internal/dispatcher/dispatcher_test.go
  • cli/dispatcher/shared-inputs-stamp.json
  • cli/project-runner/shared-inputs-stamp.json
  • cli/release-automation/cmd/check-codeql-sarif/main.go
  • cli/release-automation/cmd/check-codeql-sarif/main_test.go
  • cli/release-automation/cmd/check-dispatcher-pin/main.go
  • cli/release-automation/cmd/check-dispatcher-pin/main_test.go
  • cli/release-automation/cmd/stamp-dispatcher-pin/main.go
  • cli/release-automation/internal/architecture/architecture_test.go
  • cli/release-automation/internal/automation/codeql_sarif_guard.go
  • cli/release-automation/internal/automation/codeql_sarif_guard_test.go
  • cli/release-automation/internal/automation/dispatcher_pin_guard.go
  • cli/release-automation/internal/automation/dispatcher_pin_guard_test.go
  • cli/release-automation/internal/automation/dispatcher_pin_stamp.go
  • cli/release-automation/internal/automation/dispatcher_pin_stamp_test.go
  • cli/release-automation/internal/automation/release_trigger_guard.go
  • cli/release-automation/internal/automation/testdata/codeql-cli-2.26.0-sarif.json
  • cli/release-automation/internal/automation/testdata/codeql-cli-2.26.0-security-probe-sarif.json
  • docs/dispatcher-pin-release-order.md
  • docs/security-scan-engine-decision.md
  • scripts/install.sh
  • scripts/stamp-release-inputs.sh
  • scripts/test-bootstrap-manifest-from-bundle.sh
  • scripts/test-dispatcher-publish-workflow.sh
  • scripts/test-install-archive-manifest.sh
  • scripts/test-install-release-filter.sh
  • scripts/test-native-cli-publish-workflow.sh
  • scripts/test-security-scan-workflow.sh
  • tests/contracts/endpoint_contract.json
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch security/cli-distribution-hardening-integration

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.

❤️ Share

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

@hatayama
hatayama merged commit b5ca16b into v3-beta Jul 15, 2026
14 of 15 checks passed
@hatayama
hatayama deleted the security/cli-distribution-hardening-integration branch July 15, 2026 13:17
@github-actions github-actions Bot mentioned this pull request Jul 14, 2026
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