BeeBuzz Architecture: Designing for Minimal Trust
Building BeeBuzz, I kept coming back to one idea: design for the worst case, not the best one.
Not because I expect things to go wrong — but because assuming they might forces better decisions. No server is perfect. Dependencies have bugs. People make mistakes. So instead of pretending everything is secure, I designed BeeBuzz to limit the damage if something does break.
Keeping Scope Small
BeeBuzz does one thing: deliver notifications triggered by events.
I could have added chat, workflows, multiple roles. I didn’t want that. Fewer moving parts make it easier to understand what’s happening and keep the attack surface small. Notifications are plain text — emoji are fine, rich formatting is not. A narrow scope also makes the codebase easier to audit — which matters more than it might seem.
Encrypted Mode vs Trusted Mode
One of the early choices was supporting two modes — and making both feel like first-class options, not a “secure mode” and a “lazy mode.”
In privacy E2E mode, the sender encrypts the payload client-side before it ever leaves their device. The server receives ciphertext, stores it, and notifies the client. The client downloads and decrypts on demand — the server never sees the content.
But E2E is only possible when you control the sender.
If a notification is triggered by a third-party service — a webhook from a CI pipeline, an alert from a monitoring tool, an event from an external API — the payload arrives at the server in plaintext by definition. You can’t E2E-encrypt something you didn’t originate. In those cases, trusted server mode isn’t a compromise, it’s just the reality of how the web works. The server encrypts the attachment itself, stores it, and notifies the client. The client downloads and decrypts on demand, just like in E2E mode.
In both cases, the push notification never carries the attachment — only a reference to it. The file always lives encrypted at rest and is decrypted on device.
The two modes aren’t a hierarchy. E2E mode is for when you own both ends of the pipe. Trusted mode is for everything else — and it’s still treated carefully.
One thing worth noting: in both modes, the Web Push notification itself is encrypted in transit between BeeBuzz and your device (RFC 8291). The push provider — FCM, Mozilla, or any other — never sees the content. The difference between the two modes is only about what BeeBuzz server can read, not what the transport layer exposes.
Encryption on the BeeBuzz side is handled with age — but the details of that flow deserve a post of their own.
Metadata and Data Lifetime
Even encrypted messages leak information through metadata. I tried to minimize what’s stored: only what’s needed for delivery, no extra identifiers, temporary data cleaned up automatically.
Messages are never stored server-side — they’re delivered and gone. Attachments are the only thing that lives on the server, and they expire after 24 hours.
If data doesn’t need to exist, don’t keep it.
Why Web-Only
Native apps bring background services, persistent storage, app store rules — complexity I didn’t want. Staying web-only keeps the surface smaller and easier to reason about. It also means I can maintain this in my spare time without losing my mind.
Self-Hosted vs SaaS
The same core powers both. Self-hosting gives full control over infrastructure. The SaaS version exists because I use it myself, and for anyone who wants the same thing without running a server.
Making both work meant designing the system to behave predictably across different environments — which turned out to be a useful constraint in itself.
Auditability
Because BeeBuzz is open source, the architecture has to be easy to follow. One concrete example: I keep encryption and decryption confined to clearly defined boundaries, so there’s no ambiguity about what the server sees at any point. No logic scattered across layers, no implicit trust.
Anyone reading the code should be able to answer four questions without digging:
- Where is data encrypted?
- Where is it decrypted?
- What does the server actually see?
- When does data get deleted?
If those answers aren’t obvious, the design needs rethinking.
Constraints Are Intentional
No mobile apps. No feature bloat. No analytics. No complex multi-user flows.
These aren’t gaps to fill — they’re choices. Each one simplifies reasoning, reduces complexity, and reinforces the privacy model.
BeeBuzz isn’t trying to be a messaging platform. It’s meant to deliver secure notifications reliably. That focus guides every architectural decision.