docs(README): update CI workflows references to GitHub Actions and update security policy details

This commit is contained in:
Ivan
2026-04-23 19:50:53 -05:00
parent 3310b61a8f
commit ce29ee15a8
7 changed files with 70 additions and 82 deletions

View File

@@ -8,7 +8,7 @@ This project is independent from the original Reticulum MeshChat project and is
- Website: [meshchatx.com](https://meshchatx.com)
- Source: [git.quad4.io/RNS-Things/MeshChatX](https://git.quad4.io/RNS-Things/MeshChatX)
- Official Mirror: [github.com/Sudo-Ivan/MeshChatX](https://github.com/Sudo-Ivan/MeshChatX) - Also used for Windows and MacOS builds for the moment.
- Official Mirror: [github.com/Sudo-Ivan/MeshChatX](https://github.com/Sudo-Ivan/MeshChatX) - Used for GitHub Actions.
- Releases: [git.quad4.io/RNS-Things/MeshChatX/releases](https://git.quad4.io/RNS-Things/MeshChatX/releases)
- Changelog: [`CHANGELOG.md`](CHANGELOG.md)
- TODO: [Boards](https://git.quad4.io/RNS-Things/MeshChatX/projects)
@@ -58,8 +58,8 @@ Use the method that matches your environment and packaging preference.
Notes:
- The release workflow explicitly builds Linux `x64` and `arm64` AppImage + DEB.
- RPM is also attempted by release workflow and uploaded when produced.
- GitHub Actions builds tagged releases: Windows and macOS via `.github/workflows/build-release.yml`, Linux wheel/AppImage/deb/rpm via `.github/workflows/build-linux-release.yml`, and the container image via `.github/workflows/docker.yml`.
- Linux `x64` and `arm64` AppImage + DEB are built on GitHub; RPM is attempted and uploaded when produced.
## Quick Start: Docker
@@ -198,6 +198,32 @@ Or through Task:
task dist:fe:rpm
```
## Container build (wheel, AppImage, deb, rpm)
`Dockerfile.build` runs the same shell-driven steps CI uses (Poetry, pnpm, `task`, packaging APT deps). It is oriented toward **linux/amd64** (NodeSource amd64 tarball, Task amd64 binary). Default target is everything; override with a build arg.
Targets for `MESHCHATX_BUILD_TARGETS`: `all` (default), `wheel`, or `electron` (AppImage + deb for x64 and arm64, best-effort RPM, no wheel).
Build:
```text
docker build -f Dockerfile.build -t meshchatx-build:local .
```
Build only a wheel:
```text
docker build -f Dockerfile.build --build-arg MESHCHATX_BUILD_TARGETS=wheel -t meshchatx-build:wheel .
```
Copy `/artifacts` from the finished image to the host:
```text
cid=$(docker create meshchatx-build:local)
docker cp "${cid}:/artifacts" ./meshchatx-artifacts
docker rm "${cid}"
```
## Architecture Support Summary
- Docker image: `amd64`, `arm64`
@@ -318,7 +344,7 @@ Security and integrity details:
- [`SECURITY.md`](SECURITY.md)
- [`LEGAL.md`](LEGAL.md)
- Built-in integrity checks and HTTPS/WSS defaults in app runtime
- CI scanning workflows in `.gitea/workflows/`
- CI and release builds on GitHub Actions (`.github/workflows/`). Version tags also get **SLSA Build Level 3** provenance (`*.intoto.jsonl` via [slsa-github-generator](https://github.com/slsa-framework/slsa-github-generator)) and a **draft** GitHub release with binaries plus provenance for review before publishing. Verify with [slsa-verifier](https://github.com/slsa-framework/slsa-verifier) (see `SECURITY.md`). On Gitea, only `.gitea/workflows/github-release-sync.yml` is kept: for tags matching `release_*` it waits for successful GitHub workflow runs and publishes assets to a GitHub release using the `GH_PAT` and `GH_REPOSITORY` repository secrets (see `SECURITY.md`).
## Adding a Language

View File

@@ -1,97 +1,59 @@
# Security Policy
## Contact Information
## Reporting a vulnerability
If you discover a security vulnerability or have concerns about the security of Reticulum MeshChatX, please contact the lead developer using the following methods in order of preference:
If you believe you have found a **security vulnerability** in MeshChatX, please report it privately so it can be fixed before wider disclosure.
**Preferred contact (in order):**
1. **LXMF**: `7cc8d66b4f6a0e0e49d34af7f6077b5a`
For legal inquiries (non-security), contact `legal@quad4.io` or see [`LEGAL.md`](LEGAL.md).
Include enough detail to reproduce or understand the issue (what version or build you used, what you expected, what happened). Do not open a public issue for unfixed vulnerabilities.
## Security Overview
**Not security (legal, licensing, general questions):** `legal@quad4.io` or see [`LEGAL.md`](LEGAL.md).
Reticulum MeshChatX is designed with a high degree of security and privacy in mind, leveraging multiple layers of protection and modern security practices.
---
We follow the [Electron Best Security Practices](https://www.electronjs.org/docs/latest/tutorial/security).
MeshChatX is meant to be used on **trusted networks** (for example at home, on a LAN, or over a VPN you control).
### Exposing to the public internet (with authentication)
If you still put the web interface on the **public internet**, you accept much higher risk (password guessing, misconfigured TLS or proxies, automated scanning, and overload of a single-node app). If you must expose it: **turn on authentication**, use **HTTPS** with a valid certificate for the public name, **restrict who can reach the port** (firewall, VPN, or a reverse proxy with sensible rules), and **keep the application updated**. `/robots.txt` with `Disallow: /` is only a hint to crawlers, not protection.
MeshChatX is primarily intended for **local or trusted networks** (for example behind a home router or VPN). Putting the HTTP(S) UI on the **public internet** is **not recommended**: you enlarge the attack surface (credential stuffing, TLS and certificate management, reverse-proxy misconfiguration, automated scanning, and denial-of-service against the single-node service).
The app adds **rate limiting** and **lockout** for failed logins, **logging** of access attempts (viewable under Debug Logs), and **HttpOnly** session cookies with **SameSite=Lax**. These measures reduce some abuse; they do not make a public deployment “safe by default.”
If you still choose to expose it, **enable authentication**, use **HTTPS** (valid certificates on the public name), restrict **who can reach the port** where possible (firewall allowlists, VPN, or a reverse proxy with additional controls), and keep the app **updated**. The application serves **`/robots.txt`** with **`Disallow: /`** (a hint to crawlers; it is not access control). The application includes **defence-in-depth** for the login and initial-setup endpoints: **per-IP rate limiting**, **lockout** after repeated failed passwords from an address (with **trusted client** recognition after a successful login so your own browsers are less likely to be blocked during broad attacks), **logging** of access attempts (IP, User-Agent, path, time) inspectable under **Debug Logs → Access attempts**, and session cookies configured as **HttpOnly** with **SameSite=Lax**. None of this removes the inherent risks of a public-facing service; it only reduces some abuse and accident scenarios.
### What you download should match what we built
### Core Security Features
Official release binaries and packages are built in **automation on GitHub**, not by hand on a laptop. Each tagged release is intended to ship:
- **ASAR Integrity Validation**: Utilizes Electron 39 features to protect the application against tampering.
- **Backend Binary Verification**: Generates a SHA-256 manifest of the unpacked Python backend during build and verifies it on every startup.
- **Data-at-Rest Integrity Monitoring**: Snapshots the state of identities and database files on clean shutdown and warns if they were modified while the app was closed.
- **CSP Hardening**: Multi-layered Content Security Policy protection across the entire application stack.
- **Hardened Electron Environment**: Hardened security by disabling `runAsNode` and `nodeOptions` environment variables via Electron Fuses.
- **Rootless Docker Images**: Support for running in restricted environments with rootless container images.
- **Installable files** (for example AppImage, `.deb`, Windows and macOS installers, Python wheels) from that tag.
- A **software bill of materials (SBOM)** in CycloneDX form (`sbom.cyclonedx.json`) where the Linux release pipeline produces it, so you or your tools can see what went into the build.
- **Signed provenance** files (`*.intoto.jsonl`) that cryptographically tie those binaries to the **same source repository and tag** on GitHub, using the industry [SLSA](https://slsa.dev/) approach and the [slsa-github-generator](https://github.com/slsa-framework/slsa-github-generator) project. New tags also get a **draft** GitHub release so assets can be reviewed before the release is published.
### Automated Security Measures
**Docker images** published to GitHub Container Registry are built in CI and **signed with Cosign (keyless / Sigstore)** so the signature can be checked against the image digest.
The project employs continuous security monitoring and testing:
**Optional extra signatures:** If you see `*.cosign.bundle` files next to a binary, those are additional attestations from a **repository-managed signing key** (when the project enables it). They are separate from the SLSA `*.intoto.jsonl` files; either or both may be present depending on configuration.
- **Security Scanning**: `.gitea/workflows/scan.yml` runs on a weekly schedule and on pushes to `master` and `dev`. It installs frontend dependencies and runs **Trivy filesystem** vulnerabilities on the repo (`scripts/ci/trivy-fs-scan.sh`: high and critical severities, exit non-zero on findings), and **Trivy Dockerfile** misconfiguration (`trivy config --exit-code 1 Dockerfile`). The **Docker** workflow runs **Trivy** on the built image (`trivy image`) separately from that job.
- **Auth and path-safety tests**: Pytest covers HTTP **401** on protected `/api/*` when `auth_enabled` is on and no session (`tests/backend/test_notifications.py`), **ValueError** on backup/snapshot delete paths that escape storage (`tests/backend/test_security_path_and_backup.py`), and **schema upgrade** from version **N-1** (`tests/backend/test_schema_migration_upgrade.py`). Database **backup/restore** round-trips are covered in `tests/backend/test_database_snapshots.py`. Login and setup **rate limiting**, **lockout**, and **access attempt** logging are covered in `tests/backend/test_access_attempts_dao.py` and `tests/backend/test_access_attempts_enforcement.py` (including Hypothesis and HTTP smoke tests).
- **CI**: On pushes and pull requests, **`pip-audit`** (Python) and **Trivy** (`trivy fs` via `scripts/ci/trivy-fs-scan.sh`) run against the repository tree (including Node lockfiles and manifests after install where applicable).
- **Pinned Actions**: CI/CD workflows use pinned actions with full URLs to forked, vetted actions hosted on our Gitea instance (`git.quad4.io`) where an action is used at all.
- **Extensive Testing & Fuzzing**: Backend benchmarking and stress coverage to reduce instability and resource-exhaustion risks.
- **Linting & Code Quality**: Linting and static analysis run on CI paths.
### Practical tips
## Release provenance
- Prefer **official download pages** or **GitHub Releases** for your copy of the app.
- For Docker, prefer an image referenced by **digest** (`@sha256:…`) once you trust a given build, not only by a moving tag.
- If something claims to be MeshChatX but does not match published checksums or verification steps, treat it as **untrusted**.
Tagged releases are built from `.gitea/workflows/build.yml`. Release assets include a CycloneDX SBOM (`sbom.cyclonedx.json`). When the repository secret **`COSIGN_PRIVATE_KEY`** is set (PEM from `cosign generate-key-pair`, with **`COSIGN_PASSWORD`** if the key is encrypted), the workflow also produces **SLSA v1**-style cosign bundle files (`*.cosign.bundle`) next to each attested artifact.
---
Attestations are uploaded to the **Sigstore public transparency log (Rekor)** by default. The build runner must be able to reach the Rekor endpoint (default `https://rekor.sigstore.dev`; override with **`COSIGN_REKOR_URL`** if you use another instance).
## For security professionals and auditors
Commit the cosign **public** key at the **repository root** as **`cosign.pub`** so others can verify without hunting for the key out of band.
### Product controls (high level)
### Signing key rotation
- **Desktop (Electron):** Packaging and runtime follow [Electron security guidance](https://www.electronjs.org/docs/latest/tutorial/security); ASAR integrity and hardened defaults (for example fuses that reduce risky Node integration) are part of the shipped app.
- **Backend:** A SHA-256 manifest of the bundled Python backend is checked on startup to detect tampering with the on-disk payload.
- **Data at rest:** The application can detect unexpected changes to sensitive files between runs (integrity monitoring around identities and database state).
- **Web surface:** Content Security Policy is applied in depth across the stack.
- **Containers:** Images are intended to run **without root** inside the container where the platform supports it.
Rotate the signing key when it may be compromised or on an internal schedule (for example annually). Generate a new key pair, replace the **`COSIGN_PRIVATE_KEY`** (and password) secret in Gitea, and replace **`cosign.pub`** in the repository with the new public key. Releases built **before** rotation remain verifiable using the **old** public key kept alongside the download or in git history; document which key applies to which release tag if you maintain multiple keys.
### Build, supply chain, and transparency
## Verifying releases
Install **[cosign](https://docs.sigstore.dev/cosign/installation/)**. Download the release artifact and its matching **`artifact.cosign.bundle`** from the same release page.
Use a **permalink** to the public key that matches the signing key for that release (same tag or commit as the release, or a known-good commit that still documents the key you trust). Example (replace with your tag or commit as needed):
- **Immutable commit (raw key):**
`https://git.quad4.io/RNS-Things/MeshChatX/raw/commit/a3ce41148e6b044d9dc78f2a024fec91d343edb9/cosign.pub`
**Bash or zsh** (no separate key file; process substitution feeds the key to cosign):
```bash
cosign verify-blob-attestation \
--key <(curl -fsSL 'https://git.quad4.io/RNS-Things/MeshChatX/raw/commit/a3ce41148e6b044d9dc78f2a024fec91d343edb9/cosign.pub') \
--bundle ./MeshChatX-Example.AppImage.cosign.bundle \
--type slsaprovenance1 \
./MeshChatX-Example.AppImage
```
If your shell does not support `<(...)`, download the key once and pass a path:
```bash
curl -fsSL -o cosign.pub 'https://git.quad4.io/RNS-Things/MeshChatX/raw/commit/a3ce41148e6b044d9dc78f2a024fec91d343edb9/cosign.pub'
cosign verify-blob-attestation \
--key cosign.pub \
--bundle ./MeshChatX-Example.AppImage.cosign.bundle \
--type slsaprovenance1 \
./MeshChatX-Example.AppImage
```
If you intentionally use a private Sigstore deployment, set the same **`COSIGN_REKOR_URL`** (and any other Sigstore env vars) your builder used.
When CI signing is disabled (no **`COSIGN_PRIVATE_KEY`**), there will be no **`.cosign.bundle`** files for that release.
### Container images
Published images are built in `.gitea/workflows/docker.yml`. **OCI image cosign signing is not wired in that workflow yet.** Until it is, treat digest pinning as the main integrity check: pull or reference the image by **`@sha256:<digest>`** from a trusted manifest or registry UI, and optionally run **`trivy image`** against that digest. When cosign image signing is added, verification will look like:
```bash
cosign verify --key cosign.pub <registry>/<image>@sha256:<digest>
```
(Exact flags may depend on keyless versus key-based signing; follow the release notes when signing lands.)
- **CI:** Automated pipelines (hosted on GitHub Actions) run dependency and configuration scanning (including **Trivy** and **pip-audit** on relevant paths), build checks, and security-relevant automated tests (authentication, path safety on dangerous operations, schema upgrades, backup/restore, rate limiting and access logging, and related areas).
- **Action pinning:** Third-party GitHub Actions are referenced with **pinned commit SHAs** in workflow definitions to reduce unexpected upgrades.
- **Releases:** Tagged release artifacts for Linux, Windows, and macOS are produced in CI. **SLSA Build Level 3style provenance** for those artifacts is generated via the **generic** SLSA GitHub generator (`generator_generic_slsa3.yml` at release **v2.1.0**), which satisfies the **isolated builder and signed provenance** expectations for that tier; **distribution** (draft releases, mirrors) and **consumer verification** remain your operational controls, as described in upstream SLSA documentation.
- **Transparency logs:** Builds that use Sigstore (including the SLSA generator path and optional Cosign signing) normally write attestations to the **public Rekor** log (`https://rekor.sigstore.dev` by default). Private-repo or air-gapped policies may require different Sigstore settings; operators should align `COSIGN_REKOR_URL` and related variables with their own governance.
- **Cosign public key:** When repository key-based signing is used, the **public** key is published in-repo as `cosign.pub` so verifiers do not need a separate out-of-band key hunt. **Key rotation:** replace the GitHub secret holding the private key and update `cosign.pub` in the repository; older releases remain verifiable with the key that was current at build time.

View File

@@ -310,7 +310,7 @@ Fuer konsistente Releases die Versionsfelder dort abgleichen, wo noetig (`packag
- [`SECURITY.md`](../SECURITY.md)
- Integrierte Integritaetspruefungen und HTTPS/WSS-Standardeinstellungen in der App
- CI-Scanning-Workflows in `.gitea/workflows/`
- CI- und Release-Workflows in `.github/workflows/`; auf Gitea nur `.gitea/workflows/github-release-sync.yml` für GitHub-Release-Sync (siehe `SECURITY.md`)
## Sprache hinzufuegen

View File

@@ -310,7 +310,7 @@ Per release coerenti, allineare i campi di versione dove richiesto (`package.jso
- [`SECURITY.md`](../SECURITY.md)
- Controlli di integrita integrati e HTTPS/WSS predefiniti nell'app
- Workflow di scansione CI in `.gitea/workflows/`
- CI e release in `.github/workflows/`; su Gitea solo `.gitea/workflows/github-release-sync.yml` per il sync delle release su GitHub (vedi `SECURITY.md`)
## Aggiungere una lingua

View File

@@ -310,7 +310,7 @@ pnpm run version:sync
- [`SECURITY.md`](../SECURITY.md)
- アプリ実行時の組み込み整合性チェックとデフォルトの HTTPS/WSS
- `.gitea/workflows/` の CI スキャンワークフロー
- CI とリリースは `.github/workflows/`。Gitea では GitHub リリース同期用に `.gitea/workflows/github-release-sync.yml` のみ(`SECURITY.md` を参照)
## 言語の追加

View File

@@ -310,7 +310,7 @@ pnpm run version:sync
- [`SECURITY.md`](../SECURITY.md)
- Встроенные проверки целостности и HTTPS/WSS по умолчанию в приложении
- CI-сканирование в `.gitea/workflows/`
- CI и релизы в `.github/workflows/`; на Gitea только `.gitea/workflows/github-release-sync.yml` для выгрузки релизов на GitHub (см. `SECURITY.md`)
## Добавление языка

View File

@@ -310,7 +310,7 @@ pnpm run version:sync
- [`SECURITY.md`](../SECURITY.md)
- 应用内置完整性检查与默认 HTTPS/WSS
- `.gitea/workflows/` 中的 CI 扫描工作流
- CI 与发版在 `.github/workflows/`Gitea 仅保留 `.gitea/workflows/github-release-sync.yml` 用于同步 GitHub Release`SECURITY.md`
## 添加语言