Features → Security

Security model designed for MSPs handling other companies' data

Per-tenant MySQL database isolation. AES-256-GCM encryption at rest. TOTP MFA + SAML SSO. 300+ granular permissions. Admin IP allowlist. ClamAV on uploads. Infisical secrets vault. Triple-codebase quarterly security audits. The defenses an MSP needs when they're the ones answering for their own customers' data.

Controls

Every item below is live in production. Where a control is plan-gated or opt-in, that's called out on the relevant feature or pricing page.

Per-Tenant MySQL Database

Each customer's data lives in a dedicated MySQL database (saas_tenant_<slug>). Not a shared schema with row-level tenant_id filters. Not multi-tenant rows you have to remember to scope. Cross-tenant queries are not possible by design — the database connection is bound to one tenant per session, period.

AES-256-GCM Encryption at Rest

PII fields (phone, address, last_four), integration tokens (OAuth refresh tokens, API keys, webhook secrets, SAML certs), and MFA secrets are encrypted with authenticated AES-256-GCM. Encryption key managed via environment variable or Infisical vault; can be rotated on-demand with a 30-day rollback window.

TLS 1.3 in Transit

All connections — web, API, customer portal, back-end — terminate TLS 1.3 with modern ciphers only. No legacy fallbacks. HSTS enabled.

Two-Factor Authentication (TOTP)

TOTP MFA available for both staff and customer-portal users. Compatible with Google Authenticator, 1Password, Authy, Microsoft Authenticator, etc. Recovery codes issued at setup. MFA secrets stored encrypted.

SAML SSO

SAML 2.0 single sign-on against Entra ID, Google Workspace, Okta, or any compliant IdP. SP-initiated and IdP-initiated. SAML logins skip TOTP by design — the IdP IS the second factor. Allowed-domains gate prevents cross-IdP user provisioning.

Role-Based Access Control (300+ Permissions)

Fine-grained permissions on 98 modules across the platform. Pre-built roles for staff, billing, sales, dispatch, and read-only — or define your own. Every API route enforces required permissions; UI is just a hint.

Admin IP Allowlist

Restrict admin-area access to specific IPs or CIDR ranges. Session cookies carried off-LAN no longer authorize destructive operations. Per-action checks (not just initial login) — a stolen cookie used from a non-allowlisted IP gets a 403, not a usable session.

Account Lockout

Per-account brute-force protection: failed_login_count + locked_until columns. 5 wrong passwords lock the account for 30 min. DB-backed so it survives PM2 restart and a distributed brute force can't reset the counter by hitting different app servers.

ClamAV Malware Scanning

Every file upload — staff and portal — runs through ClamAV before it's accepted. Fails closed if the daemon is unavailable. Layered with magic-byte type detection and an extension allowlist that blocks 50+ executable file types.

Storage Quota + Upload Hardening

Per-plan storage quotas enforced at upload time. MIME claim validated against actual magic bytes. Archive contents (zip) inspected — embedded executables rejected even though the wrapper itself is allowed.

Comprehensive Audit Logging

Every state-changing action is logged with user + IP + timestamp + entity. Audit log is decrypt-on-read (encrypted at rest, same encryption envelope as PII). Visible to the customer on every relevant entity (customer, ticket, invoice, project, KB article) plus a tenant-wide /reporting/audit view.

Session Management

DB-backed sessions with sliding-window idle timeout (30 min idle = kicked, 8 hr absolute max). Cookie attributes: HttpOnly, Secure, SameSite=Lax. Session fixation prevented via session-ID rotation after MFA verify. CSRF middleware enforces Origin + Referer headers on every state-changing method.

Secrets Vault (Infisical)

Production secrets managed via self-hosted Infisical (HA pair on the infraadmin host). App servers fetch secrets at boot via machine-identity OIDC; no plaintext secrets on disk. Per-environment + per-service secret paths. Rotation tracked in secret_rotation_history.

Encryption Key Rotation

On-demand AES-256-GCM key rotation across all tenant databases. Rolling rollout per app server (drain → rotate → re-encrypt → restart). Old keys retained for 30 days for rollback. Audit-logged with start + complete timestamps.

QuickBooks Drift Detection

Edits made inside QuickBooks after sync are flagged on the next round-trip. Banner appears on the invoice/estimate with the diff — you decide which side is the source of truth, rather than discovering the discrepancy at audit time.

Webhook Authenticity

Outbound webhooks HMAC-SHA256 signed with a per-subscription secret so receivers can verify. Inbound webhooks (Stripe, QBO, signature providers, telephony) validate provider signatures via timingSafeEqual — replay attacks blocked by timestamp + nonce where the provider supports it.

Compliance posture

  • GDPR-aligned (data subject rights tooling, DPA available)
  • CCPA-aligned (consumer rights tooling)
  • Stripe SAQ-A scope — your team never sees raw card data
  • Per-customer data export available on request
  • Sub-processor list published at /legal/subprocessors
  • Multi-tenant SaaS — your DB is yours, not a shared row pool

SOC 2 / ISO 27001 attestations: not in scope today. We document the controls equivalent to those frameworks transparently here; formal attestations are on the roadmap for the larger customer tier.

What we verify

  • Customer-tenant data does NOT leak across tenants — verified by triple-codebase security audits (2026-05-10, 2026-05-13, 2026-05-16) covering OWASP Top 10 surfaces.
  • Encryption keys are NEVER stored in the same database as the encrypted data.
  • We do NOT store customer-of-customer credentials. If a tenant needs to track a customer's password for a service, OriginPSA refers them to an external password manager — by policy.
  • Telnet and SSH router credentials are encrypted; password-auth routers warn before use; SSH key auth is the recommended path.

Need our DPA or sub-processor list?

Data Processing Addendum at /legal/dpa. Sub-processors list at /legal/subprocessors. SLA at /legal/sla. Counter-signed copies available on request via /contact.