Comments and docs kept dating themselves: when a constraint was set, when a pair was verified, what a limit was before some day, which day a subtree was split out. A reader wants the current state, and the date goes stale faster than the sentence around it. Kept, because they are data rather than narration: ISO timestamps in test fixtures, the certificate expiry in project.yml, which an operator acts on, and docs/BUGS-2026-09-01.md, whose name is the record. ⚠️ The first pass collapsed indentation. A whitespace rule meant for prose matched YAML list items and markdown continuation lines, and project.yml stopped parsing: "did not find expected key: - path: Sources". The tests still passed, because they ran against the project generated before the break, which is exactly how this would reach somebody else. Reverted and redone without touching leading whitespace, then xcodegen was run to prove the file parses. 764 XCTest and 75 Swift Testing pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2.1 KiB
Security
Reporting a vulnerability
Email security@flamenetmessenger.com. Please do not open a public issue for anything affecting confidentiality or authentication. We acknowledge within 72 hours.
Status
Not independently audited. This iOS app has been reviewed in-house and is covered by the XCTest suite (95 checks), alongside the shared 253-check relay conformance suite and cross-platform interop tests that run the real engine on both sides.
An internal adversarial audit found and fixed a family of sender-attribution flaws: the ratchet authenticates a device, and the user id inside a sealed envelope is a claim its author chooses, the two were not bound. Devices now bind to their user on first proven use, control traffic (delivery keys, avatars) is refused from an unproven sender, and the key-transparency log head is verified against a pinned issuer key. Finding that class of bug in-house is a reason to expect more from outside review, not fewer.
What the app protects, and what it cannot
Private keys are generated on the device and live in the iOS Keychain (device-only, never in a backup). Message history is sealed at rest. The app defends against a malicious or compromised relay reading messages, and against a passive adversary recording traffic to decrypt after a quantum computer exists (when both ends publish a post-quantum identity, the safety number says which guarantee it covers).
It does not defend against:
- A compromised device. Malware with your unlock reads plaintext. The app lock is a speed bump against someone holding your unlocked phone, not encryption.
- Metadata. The relay sees who is addressed and when. Sealed sender removes the sender from the stored row, not from the network connection.
- Your correspondent. Anything you send can be screenshotted, kept, or repeated by the person you sent it to.
Verifying what you run
Every byte of the shipped APK's contents reproduces from this source; only the
randomized signing block differs. See docs/REPRODUCIBLE.md in the relay repo
and scripts/verify-build.py in the Android repo.