Skip to content

Commit 14343da

Browse files
committed
Merge PR #2621: Harden install trust model and clarify security guidance
Add SHA256 checksum verification to install scripts and reorder security verification steps in documentation. PR: #2621 Author: maphew
2 parents f9a6831 + 4d23a6c commit 14343da

File tree

6 files changed

+212
-51
lines changed

6 files changed

+212
-51
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,16 @@ Beads supports hierarchical IDs for epics:
7070

7171
**Requirements:** Linux, FreeBSD, macOS, or Windows.
7272

73+
### Security And Verification
74+
75+
Before trusting any downloaded binary, verify its checksum against the release `checksums.txt`.
76+
77+
The install scripts verify release checksums before install. For manual installs, do this verification yourself before first run.
78+
79+
On macOS, `scripts/install.sh` preserves the downloaded signature by default. Local ad-hoc re-signing is explicit opt-in via `BEADS_INSTALL_RESIGN_MACOS=1`.
80+
81+
See [docs/ANTIVIRUS.md](docs/ANTIVIRUS.md) for Windows AV false-positive guidance and verification workflow.
82+
7383
## 🌐 Community Tools
7484

7585
See [docs/COMMUNITY_TOOLS.md](docs/COMMUNITY_TOOLS.md) for a curated list of community-built UIs, extensions, and integrations—including terminal interfaces, web UIs, editor extensions, and native apps.

docs/ANTIVIRUS.md

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
Some antivirus software may flag beads (`bd` or `bd.exe`) as malicious. This is a **false positive** - beads is a legitimate, open-source command-line tool for issue tracking.
66

7+
Beads release installers now verify downloaded archives against release `checksums.txt` before installation. For users who manually install binaries, checksum verification should be the first trust step before running `bd` or creating antivirus exclusions.
8+
79
## Why This Happens
810

911
Go binaries (including beads) are sometimes flagged by antivirus software due to:
@@ -26,7 +28,27 @@ Kaspersky's PDM (Proactive Defense Module) uses behavioral analysis that commonl
2628

2729
## Solutions for Users
2830

29-
### Option 1: Add Exclusion (Recommended)
31+
### Option 1: Verify File Integrity (Recommended First)
32+
33+
Before running a downloaded binary or adding antivirus exclusions, verify the file is legitimate:
34+
35+
1. Download beads from the [official GitHub releases](https://github.com/steveyegge/beads/releases)
36+
2. Verify the SHA256 checksum matches the `checksums.txt` file in the release
37+
3. If a release includes code signing, verify that signature too
38+
39+
**Verify checksum (Windows PowerShell):**
40+
```powershell
41+
Get-FileHash bd.exe -Algorithm SHA256
42+
```
43+
44+
**Verify checksum (macOS/Linux):**
45+
```bash
46+
shasum -a 256 bd
47+
```
48+
49+
Compare the output with the checksum in `checksums.txt` from the release page.
50+
51+
### Option 2: Add Exclusion (After Verification)
3052

3153
Add beads to your antivirus exclusion list:
3254

@@ -47,26 +69,6 @@ Add beads to your antivirus exclusion list:
4769
- Look for "Exclusions", "Whitelist", or "Trusted Applications" settings
4870
- Add the beads installation directory or executable
4971

50-
### Option 2: Verify File Integrity
51-
52-
Before adding an exclusion, verify the downloaded file is legitimate:
53-
54-
1. Download beads from the [official GitHub releases](https://github.com/steveyegge/beads/releases)
55-
2. Verify the SHA256 checksum matches the `checksums.txt` file in the release
56-
3. Check the file is signed (future releases will include code signing)
57-
58-
**Verify checksum (Windows PowerShell):**
59-
```powershell
60-
Get-FileHash bd.exe -Algorithm SHA256
61-
```
62-
63-
**Verify checksum (macOS/Linux):**
64-
```bash
65-
shasum -a 256 bd
66-
```
67-
68-
Compare the output with the checksum in `checksums.txt` from the release page.
69-
7072
### Option 3: Report False Positive
7173

7274
Help improve detection accuracy by reporting the false positive:
@@ -150,7 +152,7 @@ However, results vary by antivirus vendor and version.
150152

151153
Yes. Beads is:
152154
- Open source (all code is auditable on [GitHub](https://github.com/steveyegge/beads))
153-
- Signed releases include checksums for verification
155+
- Releases include checksums for verification
154156
- Used by developers worldwide
155157
- A simple CLI tool for issue tracking
156158

@@ -178,9 +180,9 @@ False positives may still occur with new releases until the certificate builds r
178180
### Should I disable my antivirus?
179181

180182
**No.** Instead:
181-
1. Add beads to your antivirus exclusions (safe and recommended)
183+
1. Verify release checksums before first run
182184
2. Keep your antivirus enabled for other threats
183-
3. Verify checksums of downloaded files before adding exclusions
185+
3. Add beads to your antivirus exclusions only after verification if detections persist
184186

185187
## Reporting Issues
186188

docs/INSTALLING.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,17 @@ curl -fsSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/insta
7979

8080
The installer will:
8181
- Detect your platform (macOS/Linux/FreeBSD, amd64/arm64)
82+
- Verify downloaded release archives against release `checksums.txt`
8283
- Install via `go install` if Go is available
8384
- Fall back to building from source if needed
8485
- Guide you through PATH setup if necessary
8586

87+
On macOS, the script preserves the downloaded binary signature by default. If you explicitly want ad-hoc local re-signing, opt in:
88+
89+
```bash
90+
BEADS_INSTALL_RESIGN_MACOS=1 curl -fsSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash
91+
```
92+
8693
### Comparison of Installation Methods
8794

8895
| Method | Best For | Updates | Prerequisites | Notes |
@@ -199,7 +206,7 @@ Beads now ships with native Windows support—no MSYS or MinGW required.
199206
irm https://raw.githubusercontent.com/steveyegge/beads/main/install.ps1 | iex
200207
```
201208

202-
The script installs a prebuilt Windows release if available. Go is only required for `go install` or building from source.
209+
The script installs a prebuilt Windows release if available and verifies the downloaded ZIP checksum against release `checksums.txt`. Go is only required for `go install` or building from source.
203210

204211
**Dolt backend on Windows:** Supported via pure-Go regex backend. Windows builds automatically use Go's stdlib `regexp` instead of ICU regex to avoid CGO/header dependencies. If you need full ICU regex semantics, use Linux/macOS (or WSL) with ICU installed.
205212

docs/TROUBLESHOOTING.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -202,11 +202,7 @@ If you installed via Homebrew, this shouldn't be necessary as the formula alread
202202

203203
**Solutions**:
204204

205-
1. **Add bd to antivirus exclusions** (recommended):
206-
- Add the bd installation directory to your antivirus exclusion list
207-
- This is safe - beads is open source and checksums are provided
208-
209-
2. **Verify file integrity before excluding**:
205+
1. **Verify file integrity first**:
210206
```bash
211207
# Windows PowerShell
212208
Get-FileHash bd.exe -Algorithm SHA256
@@ -216,6 +212,10 @@ If you installed via Homebrew, this shouldn't be necessary as the formula alread
216212
```
217213
Compare with checksums from the [GitHub release page](https://github.com/steveyegge/beads/releases)
218214

215+
2. **Add bd to antivirus exclusions only after verification**:
216+
- Add the bd installation directory to your antivirus exclusion list
217+
- Keep antivirus enabled for everything else
218+
219219
3. **Report the false positive**:
220220
- Help improve detection by reporting to your antivirus vendor
221221
- Most vendors have false positive submission forms
@@ -970,6 +970,10 @@ bd init -v
970970

971971
If macOS blocks bd:
972972

973+
1. Verify the downloaded binary checksum matches the release `checksums.txt`.
974+
2. If you used `scripts/install.sh`, note that macOS ad-hoc re-signing is now **opt-in** (`BEADS_INSTALL_RESIGN_MACOS=1`).
975+
3. Use one of the approval paths below.
976+
973977
```bash
974978
# Remove quarantine attribute
975979
xattr -d com.apple.quarantine /usr/local/bin/bd

install.ps1

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,43 @@ function Get-WindowsArch {
136136
}
137137
}
138138

139+
function Get-ExpectedReleaseChecksum {
140+
param(
141+
[Parameter(Mandatory)]$Release,
142+
[Parameter(Mandatory)][string]$AssetName,
143+
[Parameter(Mandatory)][string]$TempRoot
144+
)
145+
146+
$checksumsAsset = $Release.assets | Where-Object { $_.name -eq "checksums.txt" } | Select-Object -First 1
147+
if (-not $checksumsAsset) {
148+
Write-WarningMsg "Release does not include checksums.txt; refusing unverified install."
149+
return $null
150+
}
151+
152+
$checksumsPath = Join-Path $TempRoot "checksums.txt"
153+
try {
154+
Invoke-WebRequest -Uri $checksumsAsset.browser_download_url -OutFile $checksumsPath
155+
} catch {
156+
Write-WarningMsg "Failed to download checksums.txt: $_"
157+
return $null
158+
}
159+
160+
foreach ($line in Get-Content -Path $checksumsPath) {
161+
$trimmed = $line.Trim()
162+
if ($trimmed -eq "") {
163+
continue
164+
}
165+
166+
$parts = $trimmed -split '\s+'
167+
if ($parts.Count -ge 2 -and $parts[1].TrimStart("*") -eq $AssetName) {
168+
return $parts[0].ToLowerInvariant()
169+
}
170+
}
171+
172+
Write-WarningMsg "No checksum entry found for $AssetName in checksums.txt"
173+
return $null
174+
}
175+
139176
function Install-FromRelease {
140177
Write-Info "Installing bd from GitHub releases..."
141178

@@ -175,6 +212,20 @@ function Install-FromRelease {
175212
Write-Info "Downloading $assetName..."
176213
Invoke-WebRequest -Uri $asset.browser_download_url -OutFile $zipPath
177214

215+
Write-Info "Verifying release checksum..."
216+
$expectedChecksum = Get-ExpectedReleaseChecksum -Release $release -AssetName $assetName -TempRoot $tempRoot
217+
if (-not $expectedChecksum) {
218+
return $false
219+
}
220+
221+
$actualChecksum = (Get-FileHash -Path $zipPath -Algorithm SHA256).Hash.ToLowerInvariant()
222+
if ($actualChecksum -ne $expectedChecksum) {
223+
Write-WarningMsg "Checksum mismatch for $assetName; refusing to install."
224+
return $false
225+
}
226+
227+
Write-Success "Checksum verified for $assetName"
228+
178229
Write-Info "Extracting archive..."
179230
Microsoft.PowerShell.Archive\Expand-Archive -Path $zipPath -DestinationPath $tempRoot -Force
180231

0 commit comments

Comments
 (0)