This document explains how we handle security for Reticulum-Go. It covers how you can report vulnerabilities, how we secure our build process, and how the runtime sandbox protects the running daemon.
For details on cryptographic primitives, key formats, and protocol behavior, please refer to the dedicated guide in docs/en/cryptography.md. You can also find the full English documentation in docs/en/.
If you find a security issue, please contact us privately first. This gives us a chance to investigate and fix the problem before it becomes public.
- LXMF Address:
f489752fbef161c64d65e385a4e9fc74 - Email:
security@quad4.io
When reporting, please include enough detail to help us reproduce or understand the issue. Useful information includes the affected component, what you expected to happen, and what actually happened. We take all reports seriously and will work with you on a reasonable timeline to resolve the issue and coordinate public disclosure.
Here is a quick look at how we secure the project in practice.
- Builds and Automation: Our continuous integration system runs automated tests and security checks on every change. We use clear, easy to audit shell scripts instead of complex third-party actions. This makes it straightforward to review exactly what runs during a pull request.
- Scanning and Analysis: We run static analysis and vulnerability scanning on our codebase and all dependencies.
- Runtime Sandbox: The
reticulum-godaemon applies operating system restrictions after it starts up. This limits access to the filesystem and system resources if the process is ever compromised. - Signed Releases: We attach official cosign signatures to all release files. These are signed with a project key, and you can find the public key in
cosign.pub.
The sections below describe these practices in detail.
All of our automation runs on GitHub Actions, with configuration files stored in .github/workflows/.
To run our builds and security scans, we use helper scripts located in scripts/ci/*.sh. These scripts install Go, Task, Node, and our security scanners. This approach keeps the setup logic in ordinary shell scripts that you can review and diff.
We take supply chain security seriously and use pinning to protect our builds:
- Third-party GitHub Actions: We pin third-party actions to specific commit hashes instead of version tags. This prevents unexpected updates from modifying our build environments. You can see these hashes in the comments at the top of our workflow files.
- Build and Security Tools: We pin the versions of all compilers and scanners inside our workflow environment blocks.
The repository root includes a signed rnid message file, reticulum-go.rsm. It embeds a SHA-256 inventory of git-tracked files except itself and paths under any vendor/ tree. CI verifies the signature against the required signer identity e46112d44649266d71fe2193e00a4710, then re-hashes file bytes. Jobs also recheck the inventory at the end so a compromised runner cannot silently add or modify tracked files.
Verify locally:
make tree-rsm-verifyMaintainers regenerate the signature after intentional tree changes (requires a private identity file that hashes to the signer above, never commit *.rid):
export RNS_ID_PATH="$HOME/.local/share/reticulum-go/reticulum-go-release.rid"
make tree-rsm-signEnable the tracked pre-commit hook so commits that change inventory paths resign reticulum-go.rsm automatically when that identity is available:
make hooks-installSkip one commit with SKIP_TREE_RSM_HOOK=1.
When we publish a release, we build the binaries, WebAssembly targets, and pageserver examples. We also generate software bills of materials (SBOMs) using Trivy.
For each release asset, we generate a signed provenance bundle using cosign. We do not use separate checksum files.
You can verify any release file using our public key and the provided verification script:
sh scripts/ci/verify-release-attestation.sh path/to/binary path/to/binary.cosign.bundleAlternatively, you can run the standard cosign command directly with the same public key and bundle.
We use several security scanners to check our codebase on every commit:
- Gosec: Scans the Go code for security issues and unsafe coding patterns.
- Govulncheck: Checks our dependencies against the official Go vulnerability database to find reachable vulnerabilities.
- Trivy: Scans our filesystem and dependencies for known vulnerabilities.
Third-party package managers can be a security risk. In early 2026, some distribution channels for Trivy were compromised when attackers updated workflow tags to distribute malicious binaries.
To protect our build pipeline, we do not download Trivy using moving tags or unverified URLs. Instead, our installation script downloads a specific release package directly from the Aqua Security release page. We check the package against a hardcoded SHA256 hash before installing it. We update this hash manually when we want to upgrade the scanner.
To protect your system, the reticulum-go daemon can restrict its own permissions after starting up. It does this by calling sandbox.Apply after it has loaded its configuration and set up its network interfaces.
This sandbox is enabled by default using the enable_sandbox = yes setting in the Reticulum configuration. If you need to disable it, you can set enable_sandbox = no. On Linux, enable_seccomp = yes is the default when the sandbox is on. Set enable_seccomp = no to skip the seccomp filter. Seccomp install failures soft-fail so the daemon continues.
The level of protection depends on your operating system:
| Operating System | Mechanism | Description |
|---|---|---|
| Linux | Landlock, seccomp-bpf, PR_SET_NO_NEW_PRIVS, resource limits |
Restricts access to ~/.reticulum-go, /tmp, $XDG_RUNTIME_DIR, system configuration folders, and DNS paths. Denies high-risk syscalls. Drops capabilities and runs in a private namespace when started as root. |
| OpenBSD | unveil, pledge |
Restricts visible filesystem paths and limits system calls to only what is needed by a network daemon. |
| FreeBSD | cap_enter, resource limits |
Enters capability mode and applies conservative resource limits. |
| macOS | Resource limits | Sets limits on memory, file descriptors, stack size, and the number of processes. |
| Windows | Job objects | Limits process creation and memory usage, and disables mini-dumps. |
| Other platforms / WASM | No-op | Logs a warning that sandboxing is not supported on the host platform. |
Landlock requires Linux kernel version 5.13 or newer. On older kernels, Landlock will fail gracefully while other Linux restrictions still apply where possible.
Please note that sandboxing is designed as defense in depth. It is not a replacement for strong cryptography, proper interface configuration, or secure hosting practices. It also does not apply to WebAssembly builds, which rely on the browser or runtime environment sandbox.
For complete details on our cryptographic algorithms, key formats, identity encryption, and packet validation, please see the guide in docs/en/cryptography.md. This file is the primary reference for the cryptography used in this project.