| Version | Supported |
|---|---|
| 2.4.x (latest) | Yes |
| < 2.4.0 | No |
Always run the latest release. ParamantOS is a purpose-built appliance image — update by flashing a new ISO or running paramant-update.
Do not open a public GitHub issue for security vulnerabilities.
Report to: security@paramant.app
Include:
- Description of the vulnerability
- Steps to reproduce
- Affected component (NixOS config, relay, SSH, scripts)
- Potential impact
You will receive an acknowledgement within 48 hours and a status update within 7 days.
Responsible disclosure: we ask for 90 days before public disclosure to allow a fix and coordinated release.
| Area | Configuration |
|---|---|
| Kernel | unprivileged_bpf_disabled=1, kptr_restrict=2, bpf_jit_harden=2 |
| SSH | Ed25519-only host key, no password auth, no root login, ML-KEM-768 KEX |
| Firewall | Only ports 22 + 3000–3004 open |
| Service isolation | Relay runs as paramant-relay system user (no shell, no login) |
| Systemd sandboxing | NoNewPrivileges, ProtectSystem=strict, PrivateTmp, PrivateDevices, RestrictNamespaces |
KexAlgorithms: mlkem768x25519-sha256, curve25519-sha256
Ciphers: chacha20-poly1305@openssh.com, aes256-gcm@openssh.com
MACs: hmac-sha2-256-etm, hmac-sha2-512-etm, umac-128-etm
HostKey: ssh-ed25519 only
Auth: publickey only — no passwords, no GSSAPI, no host-based
Forwarding: all disabled (agent, TCP, X11, tunnel)
CVE mitigations baked into the default config:
- CVE-2023-51767 — Ed25519 only (no RSA host key)
- CVE-2025-26465 —
UseDns no - CVE-2025-26466 —
LoginGraceTime 30,MaxStartups 20:50:100 - CVE-2025-32728 — all forwarding explicitly disabled
| Layer | Algorithm |
|---|---|
| KEM | ML-KEM-768 (NIST FIPS 203) |
| ECDH | P-256 |
| Key derivation | HKDF-SHA256 |
| Encryption | AES-256-GCM |
| Relay identity | ML-DSA-65 (NIST FIPS 204) |
| Fingerprinting | SHA-256 over kyber_pub ‖ ecdh_pub |
The relay is an untrusted intermediary — it holds only ciphertext, never keys or plaintext.
Full threat model: paramant-relay/docs/security.md
Every relay generates an ML-DSA-65 identity keypair on first boot. On startup it signs a registration payload (url|sector|version|timestamp) and posts it to the primary relay registry. Registrations with timestamps older than 5 minutes are rejected (replay prevention). The CT log provides an append-only Merkle chain of all relay registrations — verified_since proves how long a relay has been continuously running the same identity.
The paramant user is the sole operator of the appliance and requires NOPASSWD sudo for relay control. As of v2.4.4 the sudoers rules grant access only to two validated wrapper scripts:
| Wrapper | What it validates |
|---|---|
paramant-relay-ctl |
Service name against ^paramant-relay(-[a-z][a-z0-9-]{0,31})?$ — prevents arbitrary service start |
paramant-data-ctl |
Target path against ^/var/lib/paramant-relay(-...)?$ — prevents directory traversal |
Both wrappers live in the Nix store (immutable). Sudoers entries use the exact store path baked in at build time — no shell globs, no * wildcards.
| # | Limitation | Mitigation |
|---|---|---|
| 1 | initialPassword = "paramant123" shipped in config |
paramant-setup detects this and forces immediate change (v2.4.4+) |
| 2 | NOPASSWD sudo for relay management | Restricted to exact Nix store paths of validated wrappers only (v2.4.4+) |
| 3 | ADMIN_TOKEN and TOTP_SECRET in relay environment |
Use Docker secrets in production multi-tenant deployments |
| 4 | CT log is relay-hosted | Cross-check CT indices when auditing; Merkle chain cannot be retroactively forged |
Internal security review of both the ParamantOS image and the relay stack.
All findings addressed in ParamantOS v2.4.4 and paramant-relay v2.4.4.
| Finding | Severity | Status |
|---|---|---|
sudo wildcard paramant-relay* allows starting arbitrary services |
High | ✓ Fixed — validated wrapper scripts |
sudo wildcard /var/lib/paramant-relay-* allows path traversal |
High | ✓ Fixed — validated wrapper scripts |
Default password paramant123 not force-changed on install |
Medium | ✓ Fixed — paramant-setup detects and forces change |
SSH key format not validated before authorized_keys write |
Medium | ✓ Fixed — type prefix checked in setup + installer |
Unattended installer accepts arbitrary storage.disk path |
Medium | ✓ Fixed — regex validation against block device pattern |
paramant-cron stages unit files in world-writable /tmp |
Medium | ✓ Fixed — uses /run/paramant-tmp (mode 700) |
grep -oP PCRE extension used in paramant-setup |
Low | ✓ Fixed — replaced with sed |
eval "$@" in paramant-test helper functions |
Code quality | ✓ Fixed — bash -c "$cmd" patterns |
All critical/high/medium findings addressed in relay v2.4.1–v2.4.5.
Full report: paramant-relay/pentest-report-2026-04-08.txt
Tracking page: paramant-relay/docs/security-audit-2026-04.md