Skip to content

Repository files navigation

Pruva Sandbox

Open in GitHub Codespaces

Public Codespaces environment for running Pruva verified CVE/GHSA vulnerability reproductions. Browse the public reproduction index at pruva.dev/reproductions; each record has a permanent REPRO-* page, CVE/GHSA lookup URLs when available, and a plain-text agent-readable view.

For crawler and agent entrypoints, see SECURITY_REPRODUCTIONS.md.

How It Works

  1. Open a Codespace from a repro/<REPRO_ID> branch
  2. The pruva-verify CLI fetches the reproduction metadata and script from the Pruva API
  3. The script runs automatically inside the sandboxed container
  4. Results are reported with pass/fail status, timing, and logs

Production Handoff

~/code/pruva is the private operator and publisher. This public repository is the Codespaces execution surface. A production repro is ready only when the public repro/<REPRO_ID> branch, public API artifact, branch-local public patch when needed, and pinned ghcr.io/n3mes1s/pruva-sandbox@sha256:<digest> image are enough to run without private source, tokens, or binaries.

See docs/PRODUCTION.md for the full contract and gates.

Quick Start

Click "Open in Codespaces" on any reproduction at pruva.dev.

Or use a direct URL with any reproduction ID:

https://github.com/codespaces/new?hide_repo_select=true&ref=repro/REPRO-2026-00006&repo=N3mes1s/pruva-sandbox

Install pruva-verify Locally

Pre-built binary (recommended)

Download the latest release for your platform:

# Linux x86_64
curl -fsSL https://github.com/N3mes1s/pruva-sandbox/releases/latest/download/pruva-verify-x86_64-unknown-linux-gnu \
  -o ~/.local/bin/pruva-verify && chmod +x ~/.local/bin/pruva-verify

# Linux aarch64
curl -fsSL https://github.com/N3mes1s/pruva-sandbox/releases/latest/download/pruva-verify-aarch64-unknown-linux-gnu \
  -o ~/.local/bin/pruva-verify && chmod +x ~/.local/bin/pruva-verify

Install script

curl -fsSL https://pruva.dev/install.sh | sh

Build from source

Requires Rust 1.70+:

cd pruva-verify-rs
cargo build --release
cp target/release/pruva-verify ~/.local/bin/

Usage

# By reproduction ID
pruva-verify REPRO-2026-00006

# By GHSA ID
pruva-verify GHSA-655q-fx9r-782v

# By CVE ID
pruva-verify CVE-2025-1716

Environment Variables

Variable Default Description
PRUVA_API_URL https://api.pruva.dev/v1 API base URL
PRUVA_KEEP_DIR 1 Set to 0 to delete the work directory after verification
PRUVA_RESULTS_DIR $HOME/pruva-results Override the results directory
PRUVA_SANDBOX Set to true to skip interactive confirmation

Project Structure

.
├── pruva-verify                # Legacy bash CLI (kept as fallback)
├── pruva-verify-rs/            # Rust rewrite of pruva-verify
│   ├── Cargo.toml
│   └── src/
│       ├── main.rs             # CLI entry point and orchestration
│       ├── resolve.rs          # Input ID parsing (REPRO/GHSA/CVE)
│       ├── metadata.rs         # API metadata, script selection, artifact listing
│       ├── artifacts.rs        # Downloading, path normalization, permissions
│       ├── patch.rs            # Local + GitHub patch application
│       ├── rewrite.rs          # BASE_DIR path substitution
│       ├── runner.rs           # Script execution and result reporting
│       ├── display.rs          # Colored terminal output
│       └── env.rs              # Sandbox detection, results dir, confirmation
├── .devcontainer/
│   ├── Dockerfile              # Pre-built sandbox image
│   └── devcontainer.json       # Codespace configuration
├── docs/
│   └── PRODUCTION.md           # Public production contract and gates
├── repro-patches/              # Known-issue patches for specific reproductions
├── scripts/
│   ├── test-codespaces.sh      # Branch validation (devcontainer, API, artifacts)
│   ├── check-repro-patch-branches.sh # Patch presence on public repro branches
│   ├── test_codespaces_modal.py# Full E2E tests via Modal sandboxes
│   ├── test-production-parity.sh# pruva/Codespaces/Modal sandbox parity gate
│   ├── detect-missing-deps.sh  # Failure log analysis for missing packages
│   ├── generate-codespace-url.sh
│   └── sandbox_shell.py        # Interactive Modal sandbox shell
└── .github/workflows/
    ├── rust-ci.yml             # Rust tests, fmt, clippy on PRs
    ├── release-binary.yml      # Cross-compile + GitHub Release on tags
    ├── build-devcontainer.yml  # Docker image build and push to GHCR
    ├── test-codespaces.yml     # Branch, optional container, and real Codespaces checks
    └── scan-new-repros.yml     # Discover and test new reproductions

Development

Running Rust tests

cd pruva-verify-rs
cargo test

The test suite covers input validation, artifact path normalization, script selection logic, patch application, path rewriting, and script execution.

Running integration tests

# Validate repro branch configuration against the API with bounded parallelism
./scripts/test-codespaces.sh --latest 10 --max-parallel 4

# Real GitHub Codespaces smoke test, matching the web UI creation path.
./scripts/test-codespaces-gh.sh --repro-id REPRO-2026-00185

# Full Codespaces execution check through gh's SSH transport.
./scripts/test-codespaces-gh.sh --repro-id REPRO-2026-00185 --mode verify

# Latest-N real Codespaces execution with bounded parallelism.
./scripts/test-codespaces-gh.sh --latest 20 --mode verify --max-parallel 3

# Bulk runtime verification in one warmed Codespace. This is faster for
# running many repro scripts, but it does not replace branch-specific startup
# checks.
./scripts/test-codespaces-bulk-gh.sh --latest 5 --per-repro-timeout 45m

# Optional raw-container smoke test in CI. This does not apply devcontainer
# features such as docker-outside-of-docker or sshd.
gh workflow run test-codespaces.yml -f latest_count=20 -f container_smoke=true

# Real Codespaces test in CI. Configure a CODESPACES_PAT repository secret with
# Codespaces scope first.
gh workflow run test-codespaces.yml \
  -f latest_count=20 \
  -f codespaces_mode=verify \
  -f codespaces_max_parallel=3

# The devcontainer uses Docker outside of Docker for the host socket and installs
# Compose v2 through the Docker CLI plugin only. The legacy docker-compose shim
# is disabled to avoid an extra mutable GitHub-release download during Codespaces
# startup.

# Full E2E test via Modal (requires MODAL_TOKEN_ID/MODAL_TOKEN_SECRET)
uv run python scripts/test_codespaces_modal.py --latest 5

# Development only: test local pruva-verify changes before publishing an image.
# Production checks leave this off and use the binary already in the image.
uv run python scripts/test_codespaces_modal.py --latest 5 --inject-verify

# Reuse expensive setup artifacts for long repro reruns.
# The final vulnerability checks still run fresh every time.
uv run python scripts/test_codespaces_modal.py \
  --repro-ids REPRO-2026-00185,REPRO-2026-00183,REPRO-2026-00172 \
  --cache-volume pruva-repro-cache \
  --max-parallel 2

# Test an immutable production candidate image
PRUVA_SANDBOX_IMAGE='ghcr.io/n3mes1s/pruva-sandbox@sha256:<digest>' \
  uv run python scripts/test_codespaces_modal.py --latest 20

# Structural parity gate for public repro branches and patch portability.
./scripts/test-production-parity.sh --skip-modal

# Public/private boundary check for patch-only changes.
./scripts/check-public-boundary.sh

# Ensure every public patch is present on the repro branch Codespaces opens.
./scripts/check-repro-patch-branches.sh

# Local private pruva checkout readiness for publishing into Codespaces.
./scripts/audit-pruva-handoff.sh --pruva-repo ~/code/pruva --ref origin/main

# Optional image-backed rollout proof when an executor really used the promoted image.
./scripts/check-production-rollout-proof.sh \
  --repro-id REPRO-2026-00186 \
  --max-parallel 8 \
  --sandbox-image ghcr.io/n3mes1s/pruva-sandbox@sha256:<digest>

# Production parity gate including real Codespaces startup verification.
./scripts/test-production-parity.sh \
  --real-codespaces \
  --codespaces-mode verify \
  --codespaces-max-parallel 3 \
  --readiness-max-parallel 3

# Require Modal for the production gate.
./scripts/test-production-parity.sh --require-modal --modal-repro-ids REPRO-2026-00185

# Require Modal and reuse setup cache for long repro reruns.
./scripts/test-production-parity.sh \
  --require-modal \
  --modal-repro-ids REPRO-2026-00185,REPRO-2026-00183,REPRO-2026-00172 \
  --modal-cache-volume pruva-repro-cache

Releasing a new binary

Tag a version to trigger the release workflow:

git tag v0.1.0
git push origin v0.1.0

This cross-compiles binaries for x86_64 and aarch64 Linux and uploads them to the GitHub Release. The devcontainer image builds pruva-verify from the same checked-out source commit, so Codespaces does not depend on a separate release being published first.

Docker-in-Docker for Special Cases

Some reproductions require specific OS versions, library versions, or network isolation. For these, use Docker-in-Docker:

SANDBOX_IMAGE="${PRUVA_SANDBOX_IMAGE:-$(jq -r '.image' .devcontainer/devcontainer.json)}"

docker run --rm \
  -e PRUVA_SANDBOX=true \
  -e REPRO_ID=REPRO-2026-00006 \
  "$SANDBOX_IMAGE" \
  pruva-verify REPRO-2026-00006

When to use Docker-in-Docker:

  • Kernel vulnerabilities requiring specific kernel versions
  • Library vulnerabilities requiring exact vulnerable versions
  • Network isolation for simulating attack scenarios
  • Reproductions that modify system-level configurations

Security

  • Reproductions run in isolated Codespace containers
  • Scripts are fetched from the official Pruva API
  • Each reproduction exploits a real vulnerability — review before running locally

Links

About

Public Codespaces runner for verified CVE/GHSA vulnerability reproductions

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages