Advanced Users Only
This guide is intended for advanced users who want to independently verify that their beta builds are reproducible and authentic. This process requires familiarity with command-line tools, Git, and build systems.
Overview
Reproducible builds ensure that identical source code produces identical binary outputs. This allows you to independently verify that the beta build you received was generated from the exact source code without unauthorized modifications. By rebuilding from the same source and comparing results, you can confirm the software’s authenticity and integrity.
Prerequisites
Before starting, ensure you have:
- Basic familiarity with command-line interfaces
- Essential command-line tools installed
- Access to the beta build file you want to verify
- A clean environment
Required Tools
The verification process requires command-line tools that are pre-installed on most systems:
- Git: For cloning the repository and checking out specific commits
- curl: For downloading Bun and other tools
- diff: For comparing generated files with your received build
- jq: For parsing JSON files (
manifest.json
) - bash/zsh: Shell environment for running commands
- Basic Unix utilities:
ls
,cat
,grep
,mkdir
,cd
(usually pre-installed)
These tools are pre-installed on macOS and Linux systems. Windows users may need to install them separately.
Installing jq
If
jq
is not installed on your system:
- macOS:
brew install jq
- Ubuntu/Debian:
sudo apt-get install jq
- Windows: Download from https://jqlang.github.io/jq/download/
Recommended Environment
For reliable verification results, use a clean macOS or Linux system in a virtual environment (such as Parallels Desktop, VirtualBox, VMware, or cloud instances). This ensures:
- No interference from existing Node.js, Bun, or other development tools
- Consistent dependency resolution
- Elimination of environment-specific variables that could affect builds
- Reproducible results that match the original CI environment
Step-by-Step Verification Process
Step 1: Extract Build Information
Open the JavaScript file you received and locate the build information section at the top. It should look like this:
/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
BUILD INFO:
Identity: ABC2EFG3JKM4PQR5
Tag: v0.199.0-beta-20990909
Commit: a1b2c3d4e5f6789012345678901234567890abcd
Nonce: 1a2b3c4d5e6f7890abcdef1234567890
Generated: 2099-09-09T01:02:03.041Z
*/
Record the following values:
- Identity: Your unique access token (without dashes)
- Tag: The Git tag used for this build
- Commit: The full commit hash
- Nonce: The cryptographic nonce used for reproducible mangling
Identity Format
The identity string is your access token with dashes removed. For example:
- Access token:
ABC2-EFG3-JKM4-PQR5
- Identity:
ABC2EFG3JKM4PQR5
Step 2: Set Up Clean Build Environment
Create a clean environment to avoid contamination from other software or configurations:
# Create a new directory for verification
mkdir vertical-tabs-verification
cd vertical-tabs-verification
# Clone the repository
git clone https://github.com/oxdc/obsidian-vertical-tabs.git
cd obsidian-vertical-tabs
Step 3: Check Out the Beta Branch and Correct Commit
Since beta builds are created from the beta
branch, you need to checkout that branch first, then the specific commit:
# Checkout the beta branch (where the original commits exist)
git checkout beta
# Verify the tag exists and points to the correct commit
git tag -l | grep "v0.199.0-beta-20990909" # Replace with your actual tag
git show-ref --tags | grep "v0.199.0-beta-20990909" # Verify tag points to correct commit
# Check out the specific commit
git checkout a1b2c3d4e5f6789012345678901234567890abcd # Replace with your actual commit hash
# Verify you're on the correct commit
git log --oneline -1
git rev-parse HEAD # Should match your commit hash
Why the Beta Branch?
Beta builds originate from the
beta
branch. When code is merged tomaster
for public release, Git creates new merge commits with different hashes. The original beta commits remain unchanged on thebeta
branch, making them necessary for accurate build reproduction. Always use thebeta
branch for verifying beta builds.
Step 4: Install Node.js and Bun
Install the exact same versions used in the CI build process:
# Install Node.js version 20 (exact version used by CI)
# Option 1: Using Node Version Manager (nvm) - Recommended
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
# Restart your terminal or run:
source ~/.bashrc # or ~/.zshrc for zsh users
nvm install 20
nvm use 20
# Option 2: Using package manager (Ubuntu/Debian)
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs
# Option 3: Using package manager (macOS with Homebrew)
brew install node@20
brew link node@20
# Verify Node.js installation (should be version 20.x.x)
node --version
npm --version
# Install Bun version 1.2.21 (exact version used by CI)
curl -fsSL https://bun.sh/install | bash -s "bun-v1.2.21"
# Or using npm with specific version
npm install -g bun@1.2.21
# Restart your terminal to ensure Bun is in PATH
source ~/.bashrc # or ~/.zshrc for zsh users
# Verify Bun installation (should be version 1.2.21)
bun --version
Version Requirements
For reproducible builds, you must use the exact same versions as the CI environment:
- Node.js: version 20.x.x
- Bun: version 1.2.21
Using different versions may result in build differences that prevent successful verification.
Step 5: Obtain and Verify the Public Key
The public key is embedded in the manifest.json file of your beta build. You need to extract and verify it:
# Extract the public key from your beta build's manifest.json
PUBLIC_KEY=$(jq -r '.publicKey' /path/to/your/received/manifest.json)
# Download the official list of valid public keys
curl -s https://raw.githubusercontent.com/oxdc/obsidian-vertical-tabs/master/KEYS.txt > KEYS.txt
# Verify the extracted public key is in the official list
if grep -q "$PUBLIC_KEY" KEYS.txt; then
echo "✓ Public key verified - found in official KEYS.txt"
else
echo "✗ WARNING: Public key not found in official list - build may be compromised"
exit 1
fi
# Create the required environment file for the build
echo "EMBEDDED_PUBLIC_KEY=$PUBLIC_KEY" > .env
Public Key Verification
Always verify that the public key from your beta build matches one of the active keys listed in the official KEYS.txt file. This ensures you’re working with an authentic build.
Security Check
If the public key is not found in KEYS.txt or matches a revoked key, do not proceed with the verification. The build may have been tampered with or compromised.
Step 6: Install Dependencies
Install the exact dependencies used during the original build:
# Install dependencies with strict lockfile enforcement
bun ci
# Verify the lockfile matches the commit
git status
Dependency Consistency
The
bun ci
command ensures you install the exact same dependency versions that were used in the original build and will fail if thepackage.json
is out of sync with the lockfile. This is crucial for reproducibility.
Step 7: Build the Initial File
Generate the initial build file using the same process as the CI workflow:
# Build in beta mode (matches the CI workflow)
bun run build:beta
# Verify the build file was created
ls -la dist/main.js
Step 8: Generate the Mangled File
Use the mangling script with your specific build parameters:
bun run mangle.mjs ./dist/main.js 1 "ABC2EFG3JKM4PQR5" "v0.199.0-beta-20990909" "a1b2c3d4e5f6789012345678901234567890abcd" "1a2b3c4d5e6f7890abcdef1234567890"
Command breakdown:
./dist/main.js
: Input file path1
: Batch count (number of variants to generate)"ABC2EFG3JKM4PQR5"
: Your identity string (access token without dashes)"v0.199.0-beta-20990909"
: Git tag"a1b2c3d4e5f6789012345678901234567890abcd"
: Commit hash"1a2b3c4d5e6f7890abcdef1234567890"
: Nonce
This generates ./dist/main-1.js
with your specific mangling parameters applied.
Step 9: Compare the Files
Compare your generated file with the received file:
# Compare files (shows differences if any)
diff ./dist/main-1.js /path/to/your/received/main.js
Step 10: Interpret the Results
Successful verification shows only timestamp differences in the build info header:
10c10
< Generated: 2099-09-09T01:02:03.041Z
---
> Generated: 2099-12-31T01:02:03.041Z
No other differences should appear. If the files are identical except for timestamps, verification is successful.
If you see other differences:
- Check that you used the correct commit hash and tag
- Verify your identity string format is correct
- Ensure you’re using the exact nonce from the build info
- Confirm all dependencies match the original build environment
Troubleshooting Common Issues
Build Fails with Dependency Errors
Symptoms: Build fails with missing dependencies or version conflicts.
# Clear cache and reinstall dependencies
rm -rf node_modules bun.lockb
bun ci
# If issues persist, check Node.js/Bun versions
node --version # Should be 20.x.x
bun --version # Should be 1.2.21
# If versions don't match, reinstall with correct versions
# For Node.js version 20:
nvm install 20 && nvm use 20
# For Bun version 1.2.21:
bun upgrade --version 1.2.21
Mangle Script Fails
Common causes and solutions:
- Missing quotes: Ensure all arguments containing special characters are quoted
- Invalid identity format: Check identity string is access token without dashes
- Wrong nonce length: Nonce must be exactly 32 hexadecimal characters
- Incorrect file path: Verify
./dist/main.js
exists before running mangle script
Example of correct command format:
bun run mangle.mjs ./dist/main.js 1 "ABC2EFG3JKM4PQR5" "v0.199.0-beta-20990909" "a1b2c3d4e5f6789012345678901234567890abcd" "1a2b3c4d5e6f7890abcdef1234567890"
Files Don’t Match
Systematic debugging approach:
-
Verify build parameters:
# Check current commit git rev-parse HEAD # Check installed dependencies bun list | head -20
-
Common parameter errors:
- Identity format: Must be access token without dashes (e.g.,
ABC2EFG3JKM4PQR5
) - Commit hash: Must be full 40-character hash, not abbreviated (case sensitive)
- Nonce: Must match exactly (32 hexadecimal characters, case sensitive)
- Identity format: Must be access token without dashes (e.g.,
-
Environment differences:
- Different operating systems may produce variations
- System timezone affects timestamp generation
- Use a clean virtual environment for best results
Environment Issues
- Use a clean virtual machine or container
- Avoid modifying system-wide Node.js or Bun installations
- Ensure no global packages interfere with the build process
Operating System Considerations:
The CI environment uses Ubuntu 22.04, which may produce slightly different results than other operating systems. For best reproducibility, consider using a Ubuntu 22.04 environment through Docker (docker run -it ubuntu:22.04 /bin/bash
), a virtual machine (Ubuntu 22.04 LTS), or WSL2 (wsl --install Ubuntu-22.04
). If using a different operating system, potential differences may include line ending variations (CRLF vs LF), file path separator differences (Windows vs Unix), and system library differences that could affect native dependencies.
System Dependencies Audit:
The build process depends on the following system tools that should be consistent:
- Git: For repository operations and commit verification
- SHA256 utilities: For hash verification (
sha256sum
on Linux,shasum -a 256
on macOS) - Standard Unix tools:
curl
,grep
,diff
,ls
,cat
- File system: Case sensitivity and permission handling
Minimizing Environment Differences:
# Ensure consistent Git configuration for line endings
git config --global core.autocrlf false
git config --global core.eol lf
# For Windows users, ensure Unix-style line endings
git config --global core.autocrlf input
Security Considerations
Why This Process Matters
Reproducible builds provide several security benefits:
- Transparency: You can verify the exact source code used
- Integrity: Ensures no unauthorized modifications were made
- Trust: Confirms the build originated from the official developer
- Auditability: Enables independent verification of build authenticity
Limitations
What this process verifies:
- JavaScript code authenticity and integrity (main.js file)
- Build reproducibility from source code
- Absence of unauthorized modifications
What this process does not verify:
- Integrity of other package files (manifest.json, styles.css)
- System-level security of your build environment
- Dependencies’ internal security (supply chain attacks)
Requirements for accurate verification:
- Build environment must closely match original CI environment
- Exact dependency versions (enforced by frozen lockfile)
- Consistent system architecture and tool versions
Additional Verification
Beyond JavaScript code verification, beta builds include additional security measures that are automatically performed when the plugin runs in Obsidian.
Automatic Verification in Obsidian
When you run a beta build, Obsidian automatically performs additional verification steps:
File Integrity Verification:
- SHA-256 hashes: Detect unauthorized modifications to all plugin files (including
styles.css
andmanifest.json
) - Multi-stage verification: Build pipeline verifies signatures and integrity at multiple points
- Extended manifest format: Contains build timestamps, file hashes, and signature data for verification
Digital Signature Verification:
- Ed25519 cryptographic signatures: Embedded in manifests to prove authenticity from the official developer
- Embedded public keys: Enable offline signature verification without external dependencies
- Tamper detection: Prevents attacks that attempt to replace or modify code during distribution
Security Warning System:
If any verification step fails, a security warning will appear in the plugin’s Settings tab with details about:
- Which files may have been modified or corrupted
- Potential security risks from unauthorized changes
- Instructions to reinstall using the Beta Helper plugin
- Option to report the issue to the developer
This automatic verification compensates for the lack of Obsidian’s official plugin store security review, enabling independent verification that beta builds are authentic and unmodified.
Manual File Verification
For manual verification of other plugin files:
# Verify CSS file integrity
shasum -a 256 ./dist/styles.css
# Check manifest signature
cat manifest.json | grep -A 10 "signature"
Verifying the Public Key from Manifest
The public key is embedded in the manifest.json file. Here’s how to verify it:
# Extract the public key from your beta build's manifest.json
PUBLIC_KEY=$(jq -r '.publicKey' /path/to/your/received/manifest.json)
# Download the official list of valid public keys
curl -s https://raw.githubusercontent.com/oxdc/obsidian-vertical-tabs/master/KEYS.txt > KEYS.txt
# Check if the public key is in the official list
if grep -q "$PUBLIC_KEY" KEYS.txt; then
echo "✓ Public key verified - found in official KEYS.txt"
# Calculate and display the key fingerprint
echo "Key fingerprint:"
echo -n "$PUBLIC_KEY" | base64 -d | sha256sum
else
echo "✗ WARNING: Public key not found in official list"
echo "This build may be compromised or using an outdated/revoked key"
fi
Key Validation Required
Always verify that the public key from your build matches an active key in KEYS.txt. Keys not found in this list should be considered suspicious and the build should not be trusted.
Dependency Audit
Dependency auditing identifies known security vulnerabilities in the project’s dependencies. This helps ensure the build environment is secure and free from known security issues.
Check for Vulnerabilities
bun audit
# Or
npm audit
Understanding Audit Results
Audit tools report vulnerabilities with different severity levels:
- Critical: Severe security impact requiring immediate attention
- High: Significant security risk that should be addressed
- Moderate: Moderate security concern
- Low: Minor security issue
- Info: Informational only
What to Do If Vulnerabilities Are Found
Do not attempt to fix vulnerabilities yourself. Instead:
- Document the findings: Save the audit output for reference.
- Report to us: Contact through GitHub Issues or Ko-fi.
- Include details: Provide the audit output and vulnerability information.
- Wait for official fix: We will address security issues in future releases.
Getting Help
If you encounter issues during verification:
- Check the logs: Review build output for specific error messages
- Verify parameters: Double-check all build information values
- Contact support: Reach out through GitHub Issues or Ko-fi
Conclusion
Successfully completing this verification process confirms that your beta build is authentic and reproducible. This provides confidence that the software you’re using was built from the exact source code without any unauthorized modifications.