Herkos

Security Policy

Herkos handles private keys and encrypted messages, so we take security reports seriously and would rather hear about a problem early than late.

Reporting a vulnerability

Please do not open a public issue for security problems.

Report it privately by email to security@herkos.email.

Useful things to include: what the problem is, how to reproduce it, which platform and version you tested, and what an attacker could achieve. A proof of concept helps a lot.

Never include your own nsec, secret key or bunker secret in a report.

We aim to acknowledge reports within a few days. Since Herkos is a small project, please allow reasonable time for a fix before disclosing publicly. We are happy to credit you in the advisory unless you prefer otherwise.

What is in scope

The Herkos application itself: key handling and storage, encryption and decryption of messages (including the NIP-59 sender checks and Bcc isolation in local_packages/nostr_mail), the app lock, relay and bridge communication, attachment handling, and the build and release pipeline. For Herkos Drive, also its protocol package (packages/herkos_drive_protocol) and the page that opens its links (herkos.app/f/); see its own section below.

What is out of scope

Known limitations, stated plainly

These are design trade-offs, not vulnerabilities. We would rather write them down than have someone discover them the hard way:

Herkos Local Relay: what it protects and what it does not

Herkos Local Relay keeps your apps' events on your device, private ones too (drafts, private lists, the envelopes you receive). This is what protects them and where the limit is, platform by platform. Report the relay's security issues the same way as any other (above).

The whole database is encrypted, its journal included (SQLite3 Multiple Ciphers, AEGIS-256). The key is 32 random bytes made on the device and kept in the system's secure storage: the Keystore on Android, DPAPI on Windows, the keyring (libsecret) on Linux. It has no password of yours, because the relay has to start on its own. Without the key the relay does not start and says so: it never opens or creates an unencrypted database, and it never deletes one it cannot open.

If… Android Windows Linux
someone copies the database file (a backup, a synced folder, a disk image) Protected Protected Protected
the device or the disk is stolen while off Protected: the key is in the Keystore Protected, unless they know your Windows sign-in password: DPAPI protects the key with it Protected, unless they know your keyring's password (nearly always your session's)
another user account on the same device Protected Protected: DPAPI is per user Protected: the keyring is per user
another app or program running as your user Protected: Android keeps each app apart and the Keystore gives the key to the relay only No: DPAPI encrypts per user, not per app; a program running as you can ask for the key just as the relay does No: your session's keyring does not keep apps apart
a rooted phone, or a tool that runs code as the app No — —
someone holds the device unlocked Only the relay's PIN or fingerprint, if you set them Same Same
someone reads the relay's memory while it runs No No No

On a desktop, the limit of DPAPI and of the keyring is that of any program: they protect against other users and against whoever takes the disk, not against a malicious program already running as you. If that case worries you, what protects you is encrypting the system disk (BitLocker, LUKS) and not running programs you do not trust. On a Linux without a keyring (no Secret Service) the relay does not start and explains why: it never keeps the key in the clear.

Who gets in, on the device itself. The relay listens on 127.0.0.1 only, and any app on the device, or a web page in the browser, can reach that address. So:

What it does not protect, here:

The local network, if you turn it on (it is off by default):

What it does not protect, here: anyone on the same network sees that the device has an open port and how much traffic goes through it, though not what; and if the device has a public address (no router in between), that port can be seen from the Internet, though it still asks for a key on your list.

Copies. The encrypted copy has a password (scrypt and XChaCha20-Poly1305): without it nobody can open it, us included. The JSONL export is not encrypted and carries your private events in the clear; the app warns you.

The lock (a PIN, plus fingerprint or Windows Hello) is asked for when the app opens, after 30 seconds away, and to approve a pairing. It is a barrier of convenience, as in Mail: it encrypts nothing. On Android, with a PIN set there are no screenshots and no thumbnail among the recent apps, and since Android 12 no other app's window can sit on top of the relay's while you use it.

Herkos Drive: what it protects and what it does not

Herkos Drive keeps your files on Blossom servers and the list of your files and folders on Nostr relays, both encrypted on your device. This is what protects them and where the limits are. The full detail is in spec-drive.md and the threat model amenazas-drive.md, in packages/herkos_drive_protocol/; what each relay and server sees is in the privacy policy. Report Drive's security issues the same way as any other (above).

What relays and servers cannot do:

What it does not protect:

How it is checked. Two internal reviews against the threat model (2 November 2026) and their fixes; tests of what each event and block shows; fuzzing of every reader of what comes from outside (events, seals, manifests, links, backups). No external audit yet: one is planned before the public beta, and its report will be published in full. Drive is still in development.

Supported versions

Security fixes are applied to the latest released version. Given the size of the project, older versions are not maintained — please update before reporting.