diff --git a/.github/workflows/rust-release.yml b/.github/workflows/rust-release.yml index fd54ddd7c..6a6b0a611 100644 --- a/.github/workflows/rust-release.yml +++ b/.github/workflows/rust-release.yml @@ -846,6 +846,14 @@ jobs: needs: [version, build, web-docker, sdk-packages, vsix] runs-on: ubuntu-latest if: startsWith(github.ref, 'refs/tags/v') + # id-token + attestations power the build-provenance step below; the + # job-level block overrides the workflow defaults, so contents/PR write + # must be restated for the release upload and Nix manifest PR. + permissions: + contents: write + pull-requests: write + id-token: write + attestations: write env: OP_VERSION: ${{ needs.version.outputs.version }} TAP_GITHUB_TOKEN: ${{ secrets.TAP_GITHUB_TOKEN }} @@ -944,6 +952,22 @@ jobs: fi grep -q "$version" release-files/install-op.sh grep -q "$version" release-files/install-op.ps1 + # Downloaders (and antivirus false-positive triage — see issue #198) + # need a way to confirm an asset is the exact file CI produced: + # a checksum manifest plus a signed SLSA provenance attestation that + # links every asset back to this workflow run and source commit + # (verifiable via `gh attestation verify`). + - name: Generate SHA256SUMS + shell: bash + run: | + set -euo pipefail + (cd release-files && sha256sum -- * | sort -k2 > ../SHA256SUMS.txt) + mv SHA256SUMS.txt release-files/ + cat release-files/SHA256SUMS.txt + - name: Attest build provenance + uses: actions/attest-build-provenance@v2 + with: + subject-path: release-files/* - name: Prepare release body id: body shell: bash @@ -968,6 +992,10 @@ jobs: printf '\n## Web Docker Image\n\n' printf -- '- Image: `%s`\n' '${{ needs.web-docker.outputs.tag }}' printf -- '- Digest: `%s`\n' '${{ needs.web-docker.outputs.digest }}' + printf '\n## Verify Your Download\n\n' + printf 'Every asset is listed in `SHA256SUMS.txt` and carries a signed build-provenance attestation tying it to this repository, commit, and CI run:\n\n' + printf '```bash\ngh attestation verify --repo %s\n```\n\n' '${{ github.repository }}' + printf 'Some antivirus engines heuristically flag low-prevalence installers — see [docs/security/antivirus-false-positives.md](https://github.com/%s/blob/main/docs/security/antivirus-false-positives.md).\n' '${{ github.repository }}' } >> release-body.md - name: Create / update GitHub prerelease uses: softprops/action-gh-release@v2 diff --git a/.gitignore b/.gitignore index 20c51e519..8457c49fe 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,8 @@ docs/ !/docs/security/ /docs/security/* !/docs/security/p2p-collaboration-threat-model.md +!/docs/security/antivirus-false-positives.md +!/docs/security/code-signing-policy.md !/docs/testing/ /docs/testing/* !/docs/testing/p2p-collaboration-platform-acceptance.md diff --git a/README.md b/README.md index b25adcd6b..660a4da81 100644 --- a/README.md +++ b/README.md @@ -154,6 +154,8 @@ scoop install openpencil **Linux / Windows direct download:** [GitHub Releases](https://github.com/ZSeven-W/openpencil/releases) — `.exe` (Windows), `.AppImage` / `.deb` (Linux) +> Antivirus flagged the Windows installer? That's a known heuristic false positive on new, low-prevalence releases — see [how to verify your download](docs/security/antivirus-false-positives.md). + **Nix (Linux x86_64):** ```bash diff --git a/docs/security/antivirus-false-positives.md b/docs/security/antivirus-false-positives.md new file mode 100644 index 000000000..3874bf9c2 --- /dev/null +++ b/docs/security/antivirus-false-positives.md @@ -0,0 +1,64 @@ +# Antivirus False Positives on Windows Builds + +Some antivirus engines occasionally flag the OpenPencil Windows installer +(`OpenPencil---win-setup.exe`) as a trojan or generic threat +(e.g. `Wacatac`, `Trojan.Generic`, `Unsafe.AI_Score`). These detections are +**heuristic false positives**, not evidence of malware. This page explains +why they happen and how to verify that your download is the exact file our +CI produced. + +## Why this happens + +- **Low prevalence.** Reputation-based engines (Microsoft SmartScreen, + many cloud AV heuristics) score files by how many machines have seen + them. Every new OpenPencil release is a brand-new binary with a new + hash, so it starts with zero reputation until enough users run it. +- **NSIS installer packaging.** OpenPencil ships in an NSIS installer — + the same packaging used by thousands of legitimate apps, but also + historically abused by malware droppers. Several heuristics weight NSIS + self-extractors negatively by default. +- **Certificate trust chain.** Release binaries are currently signed with + a project-local certificate rather than a CA-issued Authenticode + certificate, so Windows reports an "Unknown publisher" and AV engines + get no trust-chain signal to offset the heuristics above. Moving to a + CA-issued certificate is on the roadmap. + +## How to verify a download is genuine + +Every release is built from public source in GitHub Actions and uploaded +directly by CI — no human touches the binaries. + +1. **Checksums.** Each release attaches `SHA256SUMS.txt`. Compare it with + your download: + + ```powershell + Get-FileHash .\OpenPencil---win-setup.exe -Algorithm SHA256 + ``` + +2. **Build provenance.** Each asset carries a signed [SLSA build + provenance attestation](https://docs.github.com/en/actions/security-for-github-actions/using-artifact-attestations) + proving it was produced by this repository's release workflow at a + specific commit: + + ```bash + gh attestation verify OpenPencil---win-setup.exe \ + --repo ZSeven-W/openpencil + ``` + +3. **Build it yourself.** The entire product is open source: + + ```bash + cargo build -p op-host-desktop --release + ``` + +## If your antivirus flags a release + +- Verify the file with the steps above. If verification **fails**, delete + the file and [open an issue](https://github.com/ZSeven-W/openpencil/issues) + immediately. +- If verification passes, the detection is a false positive. Please report + it to your AV vendor (for Microsoft Defender: + ) — vendor-side + clearances are what make these warnings disappear for everyone — and + feel free to open an issue naming the engine and detection so we can + track and submit it too. diff --git a/docs/security/code-signing-policy.md b/docs/security/code-signing-policy.md new file mode 100644 index 000000000..6899d3036 --- /dev/null +++ b/docs/security/code-signing-policy.md @@ -0,0 +1,56 @@ +# Code Signing Policy + +This document describes how OpenPencil release binaries are built and signed, +and the rules the project follows for code signing. + +## What gets signed + +- **Windows:** the NSIS installer `OpenPencil---win-setup.exe` + (x64 and arm64), containing the desktop app `openpencil-desktop.exe`, the + CLI `op.exe`, and the bundled ANGLE runtime DLLs. +- **macOS:** the `.dmg` disk images and the app bundle inside them + (Developer ID signing + notarization when release certificates are + configured). + +## How releases are built + +Every release artifact is produced by the public GitHub Actions workflow +[`.github/workflows/rust-release.yml`](../../.github/workflows/rust-release.yml) +from a version tag on this repository. Binaries are compiled from the tagged +source, packaged, checksummed into `SHA256SUMS.txt`, attested with a signed +SLSA build-provenance attestation, and uploaded to GitHub Releases directly by +CI. No human handles or modifies the binaries between build and publication. + +Anyone can verify an asset's origin: + +```bash +gh attestation verify --repo ZSeven-W/openpencil +``` + +## Signing rules + +- Free code signing is provided by [SignPath.io](https://signpath.io) and a + free code signing certificate by the + [SignPath Foundation](https://signpath.org). +- We only sign artifacts built by the release workflow of this repository + from source code in this repository (including its vendored submodules, + which the same team maintains). We never sign third-party binaries or + locally built artifacts. +- Signing is performed in CI as part of the release pipeline; signing + credentials are never exported to developer machines. +- The team responsible for code signing is the same team that develops and + maintains OpenPencil and owns this source repository. + +## Privacy policy + +OpenPencil is a local-first design tool. The application does not collect or +transmit personal data or telemetry. Network access happens only for features +the user explicitly invokes (e.g. optional AI providers, collaboration, or +image search), using endpoints the user configures or enables. + +## Team + +OpenPencil is developed and maintained by the ZSeven-W organization. The +maintainers listed on the [GitHub organization](https://github.com/ZSeven-W) +are the only people with commit access to this repository and control over the +release workflow.