Ujex security model
Three-layer security
- Firestore Security Rules — ownership and tenant isolation
- Cloud Function scope checks — capability-token-based authorization on every callable
- Append-only hash-chained audit ledger — post-hoc verifiability
Identity
Every agent has a Firebase UID-equivalent. Owners (humans) own agents. Device keys are stored as sha256(deviceKey) — never plaintext. Scopes (postbox, recall, mesh, scheduler, etc.) are granted per device key.
Secrets
KMS-envelope encryption for: device keys (hashed), agent secrets, tool auth tokens, DDNS tokens, gateway certs. Cloud KMS keys never leave KMS.
Mail security
- Inbound MIME parsed, HMAC-signed at the bridge, verified at the Cloud Function
- Prompt-injection scored (heuristic regex + Gemini fallback)
- Outbound DKIM/SPF/DMARC signed (via OpenDKIM and/or Brevo's selectors)
Audit ledger
Every privileged action: audit/{seq} with sha256(prev || event). Hourly verification by Cloud Scheduler. Details.
Threat model
In scope:
- Stolen device key → revoke via callable, audit log records the rotation
- Compromised owner password → Firebase MFA + revoke-all-tokens via Admin SDK
- Prompt injection in inbound email → PI score surfaced; agent routes high-PI to human approval
- Tampering with audit log → hash chain breaks at modified row, verifier alerts
Not fully in scope:
- Compromise of the underlying Firebase project (game over)
- Sophisticated prompt injection that scores low (we score; we don't claim to catch everything)
- Compromise of Cloud KMS (which would mean Google's KMS is compromised)
Reporting
Email security@ujex.dev. We respond within 48h.
FAQ
How are device keys stored?
sha256(deviceKey). The plaintext key is shown to the owner once at issuance and never again.
Is the prompt-injection scoring perfect?
No. It's heuristic regex + Gemini fallback. Scores are signals, not guarantees. Treat email as untrusted text always.
Can I bring my own KMS?
Yes — every vendor sits behind a module boundary. KMS swap is a port-rewrite, not a rip-and-replace.