Adds the PyQt6 Windows client (Homepage, Scan & results, About & updates, Settings), ClamAV scanning and quarantine, browser-download watch with an exclusive scan gate, Bolt loopback/PKCE sign-in with DPAPI key storage, Gitea release feed with checksum verification, opt-in diagnostics, and Windows/portable build tooling. Co-Authored-By: Claude Code <noreply@anthropic.com>
200 lines
8.5 KiB
Markdown
200 lines
8.5 KiB
Markdown
# BoltClam
|
|
|
|
BoltClam is a Windows desktop front-end for **ClamAV**, built with PyQt6 and
|
|
signed in with a Bolt account. It scans every user's home or the full disk,
|
|
quarantines or deletes what ClamAV finds, watches browser downloads, and
|
|
receives update notifications from the private Gitea release feed.
|
|
|
|

|
|
|
|
## What it does
|
|
|
|
- **Homepage** — a live protection summary: a shell gauge for engine,
|
|
definitions, real-time protection and system firewall; security concerns;
|
|
network details; recent detections; the signed-in user and Bolt plan.
|
|
- **Scan & results** — user-home or full-disk scans, live progress, scan
|
|
history, per-detection actions, and a quarantine manager with restore.
|
|
- **About & updates** — app version, account and subscription, ClamAV
|
|
version/definitions, release notes, beta/release channels, and
|
|
checksum-verified downloads.
|
|
- **Settings** — update channel, ClamAV install location, extra clamscan
|
|
options, real-time protection, automatic response, logging/debug, and
|
|
opt-in diagnostics upload to Bolt.
|
|
- **Browser download protection** — watches the configured download folder
|
|
of Chrome, Edge, Brave, Firefox, Vivaldi and Opera (plus every readable
|
|
user's Downloads folder), waits for the file to settle, holds it with an
|
|
exclusive Windows handle while ClamAV scans a copy, then quarantines or
|
|
deletes it according to the setting.
|
|
- **Bolt sign-in** — opens a Bolt-hosted sign-in page in the default
|
|
browser, receives a one-time code on a loopback listener, and exchanges it
|
|
through PKCE for an ordinary `bolt_live_...` API key. The key is stored
|
|
with Windows DPAPI; the password is never seen or stored by BoltClam.
|
|
|
|
## Requirements
|
|
|
|
- Windows 10 or 11, x64.
|
|
- [ClamAV for Windows](https://www.clamav.net/downloads) installed separately.
|
|
BoltClam does not bundle ClamAV binaries.
|
|
- A Bolt account (the same account used by the iOS/Android/Boltville clients).
|
|
- Internet access for sign-in, updates, and the first signature download.
|
|
- Administrator rights are optional but improve coverage of other users'
|
|
profiles and protected files.
|
|
|
|
## Install
|
|
|
|
### Portable build
|
|
|
|
1. Download `BoltClam-1.0.0-windows-x64-portable.zip` and extract the whole
|
|
folder (not just `BoltClam.exe`).
|
|
2. Run `BoltClam.exe`.
|
|
3. Sign in with your Bolt account in the browser.
|
|
4. Install ClamAV, open **Settings → ClamAV engine**, choose
|
|
`clamscan.exe` (or use **Auto-detect**), and click **Update definitions**.
|
|
5. Run a scan from **Scan & results**.
|
|
|
|
The portable build is assembled by
|
|
`packaging/build_portable_windows.py` from official Python Embeddable,
|
|
PyQt6 wheels, and the tiny `packaging/launcher.c` bootstrap. It is not signed;
|
|
Windows SmartScreen may warn about an unknown publisher. Compare the SHA-256
|
|
in `SHA256SUMS.txt` with the release.
|
|
|
|
### Installer / PyInstaller
|
|
|
|
On a Windows build machine with Python 3.11 x64:
|
|
|
|
```powershell
|
|
.\build_windows.ps1
|
|
```
|
|
|
|
This creates a one-folder build under `dist\BoltClam\`, a zip, and — when
|
|
Inno Setup 6 is installed — `dist\BoltClam-1.0.0-Setup.exe`.
|
|
Use `.\build_windows.ps1 -OneFile` for a single-file `BoltClam.exe`.
|
|
`build_windows.bat` is a double-click wrapper.
|
|
|
|
## Updates
|
|
|
|
Release notifications are read from:
|
|
|
|
<https://git.themajesticnetwork.com/TheMajesticNetwork/BoltClam>
|
|
|
|
BoltClam calls the Bolt API (`/boltclam/updates`) rather than the Gitea API
|
|
directly, so the Gitea token stays server-side. The API normalizes releases,
|
|
filters them by channel, and proxies asset downloads:
|
|
|
|
- **Release** channel: stable releases only.
|
|
- **Beta** channel: prereleases and stable releases.
|
|
- Assets are downloaded through the API with the user's Bolt key.
|
|
- If the release publishes `SHA256SUMS.txt`, the downloaded installer/zip is
|
|
verified before it is offered for installation.
|
|
|
|
The Gitea repo is currently public and starts empty. The first release is
|
|
created by pushing a `v*` tag once a Windows build runner is available (see
|
|
`.gitea/workflows/windows-release.yml`) or by running `build_windows.ps1` on
|
|
Windows and uploading the assets with `packaging/publish_release.ps1`.
|
|
|
|
## Server API
|
|
|
|
The BoltClam client uses the desk API at
|
|
`https://api.themajesticnetwork.com` by default:
|
|
|
|
| Endpoint | Purpose |
|
|
|---|---|
|
|
| `GET /desk/auth/boltclam/start` | BoltClam-branded browser sign-in page; validates loopback redirect + PKCE. |
|
|
| `POST /desk/auth/boltclam/login` | Email/password form handler; returns a one-time code to the app. |
|
|
| `GET /desk/auth/oauth/{google\|discord}/start` | Existing provider flow, reused by the page's OAuth buttons. |
|
|
| `POST /desk/auth/oauth/exchange` | Existing PKCE exchange; mints the `bolt_live_...` key. |
|
|
| `GET /boltclam/account` | User, username/email, plan/subscription, balance. |
|
|
| `GET /boltclam/updates?channel=release\|beta` | Normalized Gitea release feed. |
|
|
| `GET /boltclam/updates/<release_id>/assets/<asset_id>` | Authenticated asset proxy. |
|
|
| `POST /boltclam/logs` | Opt-in diagnostics zip upload. |
|
|
| `GET /boltclam/admin/logs` | Owner-only log listing (master desk key). |
|
|
|
|
The server implementation lives in
|
|
`/home/themajesticmagician/Documents/Server/tmn-api/ai/boltclam_api.py`
|
|
(plus the small registration in `ai/desk_api.py` and the `boltclam` client
|
|
name in `ai/desk_auth.py`). See `docs/BOLTCLAM.md` in that repository for
|
|
deployment notes.
|
|
|
|
## Security and privacy
|
|
|
|
- The Bolt password is sent only to the Bolt-hosted sign-in page/API.
|
|
BoltClam receives a device-scoped API key, stored with Windows DPAPI.
|
|
- Signing out revokes only this PC's key.
|
|
- No API key is written to settings or diagnostics.
|
|
- Diagnostics upload is off by default. When enabled and explicitly sent,
|
|
the zip contains app logs, settings, scan/quarantine summaries, a system
|
|
summary and the account email. Tokens and passwords are redacted, emails
|
|
in logs are redacted, and user-profile path prefixes become
|
|
`%USERPROFILE%`. File contents are never included.
|
|
- Quarantine files are renamed to `.quarantine`, made read-only/hidden where
|
|
possible, and recorded with SHA-256 plus a JSON sidecar.
|
|
- ClamAV extra options that would delete or move files (`--remove`, `--move`,
|
|
`--copy`) are refused; remediation stays in BoltClam so it is recorded and
|
|
reversible.
|
|
|
|
**Real-time protection is user-mode, not a kernel filter driver.** Holding a
|
|
file with `dwShareMode = 0` makes Windows refuse other opens while ClamAV
|
|
scans a copy, which is a strong speed bump, but it is not a guarantee against
|
|
a kernel-level bypass. If another process already has the file open, BoltClam
|
|
falls back to scanning a copy and records that in the event detail. Read
|
|
[`docs/SECURITY.md`](docs/SECURITY.md) before relying on it as the only
|
|
anti-malware layer.
|
|
|
|
## Development
|
|
|
|
```bash
|
|
python3 -m venv .venv
|
|
.venv/bin/pip install -r requirements-dev.txt
|
|
.venv/bin/pip install -e .
|
|
.venv/bin/python -m boltclam
|
|
QT_QPA_PLATFORM=offscreen .venv/bin/python -m pytest tests -q
|
|
```
|
|
|
|
The app reads `BOLTCLAM_API_URL` to override the API base (useful for a
|
|
local desk API). Tests redirect config/data with `BOLTCLAM_CONFIG_DIR` and
|
|
`BOLTCLAM_DATA_DIR`; never point those at a real user profile.
|
|
|
|
## Repository
|
|
|
|
```text
|
|
BoltClam/
|
|
├── src/boltclam/ application, services and PyQt pages
|
|
├── tests/ unit and offscreen UI tests
|
|
├── resources/ icon, stylesheet rasters and OFL fonts
|
|
├── packaging/ Windows portable builder, launcher, release helper
|
|
├── installer/ Inno Setup script
|
|
├── build_windows.ps1 PyInstaller + installer build on Windows
|
|
├── BoltClam.spec PyInstaller definition
|
|
└── .gitea/workflows/ Windows release workflow
|
|
```
|
|
|
|
## Push / release
|
|
|
|
The remote is already configured:
|
|
|
|
```bash
|
|
git remote -v
|
|
# origin https://git.themajesticnetwork.com/TheMajesticNetwork/BoltClam.git
|
|
```
|
|
|
|
Push the initial commit (Git will ask for your Gitea credentials/token):
|
|
|
|
```bash
|
|
git push -u origin main
|
|
git push origin v1.0.0
|
|
```
|
|
|
|
Pushing the tag triggers the Windows release workflow **if** the repository
|
|
has a Windows Actions runner and a `GITEA_TOKEN` secret. Without such a
|
|
runner, build on a Windows PC with `build_windows.ps1` and upload the
|
|
artifacts with `packaging/publish_release.ps1`.
|
|
|
|
## Licensing
|
|
|
|
BoltClam is internal software for The Majestic Network; no public license is
|
|
granted by this repository. **PyQt6 is GPLv3-or-commercial**: distributing
|
|
BoltClam binaries under proprietary terms requires a commercial PyQt license,
|
|
or GPLv3 compliance. ClamAV is GPLv2 and is installed separately, not
|
|
bundled. Fonts are under the SIL Open Font License. See
|
|
[`THIRD_PARTY_NOTICES.md`](THIRD_PARTY_NOTICES.md).
|