Threat model

Explicit statement of what customsso + customsso-manager defend against, what they don't, and what assumptions the security model rests on. Written for community / security review.

Assets being protected

Listed roughly by sensitivity, highest first.

  1. The GPG signing key (046E8CA0EE6A755B) — controls what code every PBX trusts as "VoIP Stuff". A leak = ability to publish malicious updates to every paired PBX.
  2. The manager's master AES key (/etc/customsso-manager/master.key) — decrypts every per-PBX HMAC secret and SSH private key stored in the manager DB. A leak + DB access = fleet-wide control.
  3. Per-PBX SSH private key — the only auth channel between manager and PBX at v0.5+. from=-restricted root shell on that PBX from the manager's IP.
  4. Per-PBX HMAC secret — ability to mint valid SSO landing tokens for that PBX, becoming the configured admin user.
  5. Manager admin credentials — bcrypt-hashed; one human's compromised account = ability to use whatever role they have.
  6. The audit log — read-only forensic record; integrity matters more than confidentiality.

Threat actors considered

Actor Capabilities assumed In scope?
Unauthenticated internet attacker Can reach manager + PBX network ports ✅ Yes — primary threat
Authenticated low-privilege user on the manager (operator / readonly) Valid login, restricted role ✅ Yes — least-privilege model
Attacker who obtains the SSH root password at the moment of pair (window: seconds, then wiped) Same as legitimate operator during pair window ✅ Yes — race-to-pair concern
Compromised single PBX Root on one paired PBX ✅ Per-PBX-isolation — that PBX's keys leak; others stay safe
Compromised manager OS (root) Full root on the manager host ❌ Out of scope — root has the master key
Compromised admin workstation Keylogger / session hijack on the operator's laptop ❌ Out of scope — has whatever the operator has
Insider with legitimate superuser access Acting maliciously ⚠️ Partial — every action audited, but actions are not prevented
Sangoma/FreePBX itself going hostile Upstream framework backdoors the agent's host environment ❌ Out of scope — we run inside FreePBX
Nation-state with cryptographic novel attacks Breaks AES-256-GCM, ed25519, SHA-256, bcrypt ❌ Out of scope

Specific attack scenarios + our defenses

1. Public-internet attacker probes the manager UI

2. Public-internet attacker probes the PBX at network level

3. Network attacker MITM's manager → PBX traffic

4. SSH root password intercepted during pair

5. Compromised single PBX tries to attack the manager

6. SQL injection on the manager web app

7. XSS on the manager web app

8. CSRF against the manager

9. Compromised SSH key for one PBX

10. Malicious admin with superuser role

Cryptographic primitives + threat assumptions

Primitive Used for Assumed safe against
AES-256-GCM Master-key encryption of *_ct columns Brute force, known attacks; AEAD provides tampering detection
HMAC-SHA256 SSO landing token signing Forgery without the secret
ed25519 Per-PBX SSH keys Key recovery without the private key; signature forgery
SHA-256 Module sig hashes Preimage / second-preimage attacks
bcrypt (PASSWORD_DEFAULT) Admin password hashes Offline dictionary attacks at well-chosen cost factor
GPG (RSA) Module signing key 046E8CA0EE6A755B Algorithm-level break (would catastrophically break Sangoma + every distro signing infrastructure too)
random_bytes() Nonces, ed25519 keys, master keys CSPRNG output unpredictability
hash_equals() Token signature comparison Timing-attack-based discovery of HMAC bits

We do not roll our own crypto. Every primitive used is the language-standard implementation (openssl_*, random_bytes, password_*, OpenSSH's ssh-keygen, system GPG).

Known limitations

Things a fleet operator MUST know before deploying, ranked by likelihood of biting real users:

  1. HTTPS is mandatory end-to-end. Cross-origin iframe cookies over plain HTTP are blocked by every modern browser (RFC 6265bis). The Native UI feature simply won't work HTTP-mode. Use self-signed certs during install; certbot on prod.
  2. Every SSO click lands on the PBX as user admin. Sso::DEFAULT_TARGET_USER = 'admin' is hardcoded. FreePBX-side audit shows admin for anything a manager operator did through SSO. Fine for solo-admin fleets; a real problem for multi-tenant / multi-operator use. Per-user SSO attribution is on the roadmap.
  3. Native UI iframe resets on tab switch. No cross-tab DOM persistence at v0.5. Every switch back to Native UI mints a fresh SSO token + reloads the iframe. Working as intended given the "each tab is a page nav" architecture. SPA-ify to fix.
  4. Boot-token race window. Between install.sh printing the setup URL and the operator claiming it, anyone with local read on /etc/customsso-manager/first-run.token could hijack the setup. Mitigation: claim the URL immediately after install, don't leave the box in setup-pending state.
  5. Master key on disk alongside the encrypted data — limited defense against full-disk theft. See LUKS tradeoffs in SECURITY.md. Manager BACKUPS must include the master key or all secrets are unrecoverable.
  6. Root SSH password used exactly once at pair time. A network capture during the pair TCP session (SSH is encrypted, so this needs a broken SSH cipher, MITM against the manager's Paramiko host-key check, or shoulder surfing on the operator) could yield the pre-wipe password. In practice: seconds of exposure, then destroyed on the PBX.
  7. Source-IP allowlist on the SSH authorized_keys line is single-IP (no CIDR, no multi-IP). A manager behind a load balancer or NAT change needs a re-pair or manual authorized_keys edit.
  8. No signed audit log — append-only by convention only. A root attacker on either host could doctor the audit table. Detect via off-host shipping (syslog forwarding, not bundled).
  9. The sidecar's SSH command allowlist for bulk operations is edited via the UI (Settings → Custom commands) — admins can define arbitrary shell templates. The templates run as root on every selected PBX. Treat the "admin" role as equivalent to fleet-wide root, per role docs.
  10. 2FA is email-code only. TOTP (authenticator apps) is v0.5+ candidate.

Reporting issues

If you find a vulnerability — please don't open a public issue. Email signing@voip-stuff.net or DM via the project's communication channels.