BSIS

Packaging

Current Zstandard executable bundles, validation and proposed compression presets.

How the prototype bundle works

The BSIS builder creates a self-contained setup executable by appending a Zstandard-compressed file payload to an existing native Windows PE runtime.

Executable bundle layout
  • BSIS-Hello-Setup.exe
    • Native Windows runtime
    • Compressed Zstandard stream
      • Payload magic and manifest length
      • Versioned package manifest
      • File content, in manifest order
    • FooterMagic, offset, length and SHA-256
Logical sections inside one executable file, not actual directories.

The builder requires a runtime compiled for Windows; a Linux binary is not interchangeable with a Windows setup executable.

Build and inspect

PowerShell · Build and inspect
cargo build --release -p bsis
cargo run -p bsis -- build --config examples/hello/bsis.json --runtime target/release/bsis.exe --output BSIS-Hello-Setup.exe
.\BSIS-Hello-Setup.exe inspect

The embedded manifest enumerates each file's relative path, byte length and SHA-256 checksum. The footer identifies the compressed stream and its digest. Ordinary inspection checks that compressed digest and the manifest; optional deep inspection also verifies each uncompressed embedded file hash.

Choose the Zstandard compression level

The prototype currently uses Zstandard only, but the builder supports selecting how aggressively it compresses files with --compression-level. The default is 3 for compatibility with existing build commands.

PowerShell · faster packaging
cargo run -p bsis --locked -- build --config examples/hello/bsis.json --runtime target/release/bsis.exe --output BSIS-Fast-Setup.exe --compression-level 1
PowerShell · prioritize compressed size
cargo run -p bsis --locked -- build --config examples/hello/bsis.json --runtime target/release/bsis.exe --output BSIS-Small-Setup.exe --compression-level 9
Zstandard levelTypical tradeoff
1Faster compression, often a larger setup file
3 (default)General-purpose build
9More compression work, potentially a smaller setup file
19Highest currently accepted setting; much slower for many inputs

Allowed levels are 1 through 19, inclusive. Invalid levels are rejected before packaging. Higher levels do not guarantee a smaller file for every data set, and they do not change the installed payload's contents or integrity verification. The entire executable contains the same version 1 Zstandard stream and SHA-256 footer regardless of the chosen level.

The level is a CLI flag on the build command, not a bsis.json configuration field. LZMA2, LZ4 and named codec presets are still planned, not implemented.

Deep verification without installing

PowerShell
.\BSIS-Hello-Setup.exe inspect --deep
.\BSIS-Hello-Setup.exe inspect --deep --json

This streams the full Zstandard payload and checks every file against its manifest SHA-256, including its declared size and absence of extra trailing data. It catches payload changes even if someone recomputes the outer compressed footer digest but leaves the manifest unchanged.

No files are extracted or installed. Deep mode uses CPU to decompress the full package. A malicious actor able to change both the manifest and payload could create internally consistent checksums, so this is not publisher authentication.

Extraction and commit

  1. Validate the package metadata and target path.
  2. Accept a new or existing empty destination directory. Reject nonempty folders and unsupported filesystem links.
  3. Create a fresh staging directory beside the target.
  4. Decompress and write each file, verifying its hash.
  5. Store the installation receipt and rename the completed stage into place. For an existing empty folder, temporarily move that folder aside and attempt restoration if the commit fails.

If extraction fails before the final rename, the temporary stage is removed. This does not provide upgrade rollback or protect against all concurrent filesystem attacks.

Integrity and limits

The runtime checks the compressed package digest and hashes extracted files against manifest entries. Invalid destination paths, conflicting names, unsupported source links and mismatched hashes are rejected.

The current Rust manifest imposes limits on manifest bytes, file count and total declared payload size. These are defensive bounds, not proof of production readiness.

SHA-256 is not a signature: a malicious publisher could generate a different executable with internally consistent checksums. Authenticode signing and verification are future work.

Future compression choices

Proposed presetCodecStatus
MaximumLZMA2Not implemented
BalancedZstandardCurrent implemented codec; selectable levels 1–19
FastLZ4Not implemented

The binary layout is provisional. Do not build tooling that assumes long-term compatibility with the current overlay or footer format.

For the manifest fields see Configuration; for install and uninstall safeguards see Security model.

Preflight a package

Before writing a Setup.exe, developers can run the read-only plan --config bsis.json [--json] command to preview sorted destination paths, file sizes and SHA-256 hashes. It catches invalid Windows destinations, missing/linked sources and collisions before compression.

Package preflight documents the command and JSON report. A plan is a snapshot, not a build cache: BSIS independently re-checks files while packaging, because they can change after the preview.