Trust & security

Built for the people who get audited.

Every control your procurement team is about to ask about. If you need a deeper artifact, request our security questionnaire response or current pen-test report under NDA.

Encryption

TLS 1.3 in flight · AES-256 at rest

All HTTP traffic over TLS 1.3 with HSTS. Database AES-256 at rest. Per-org LLM keys and SAML IdP certificates encrypted with Fernet (AES-128-CBC + HMAC-SHA256) using a separate ENCRYPTION_KEY.

Tenancy

Row-level isolation, enforced in every query

Every record is scoped by org_id at the database layer. Every API query joins through the JWT-derived org. Vendor uniqueness is per-org. The only role that bypasses scoping is super_admin (operational use).

Identity

MFA · per-org SSO (OIDC + SAML) · RBAC

TOTP MFA with 10 hashed recovery codes. Per-org OIDC and SAML 2.0 with email-domain discovery. Four built-in roles (reviewer / attestor / org_admin / super_admin) plus configurable permission groups on Growth+.

Compliance

SOC 2 Type II in progress · annual pen test

Type I gap assessment complete; Type II observation period underway. External penetration test on the production stack annually. Reports shared with Enterprise customers under NDA.

Controls

Detailed control posture

Identity & access

Authentication is bcrypt + HS256 JWT for local accounts, OIDC (authorization-code with PKCE) and SAML 2.0 for federated. Email-first discovery maps user domain to org auth methods.

  • Bcrypt password hashing with per-user salt
  • HS256-signed access tokens (15-minute expiry) + HttpOnly refresh cookie
  • TOTP MFA via pyotp with 10 hashed single-use recovery codes
  • Per-org OIDC with PKCE; JIT user creation with configurable default role
  • Per-org SAML 2.0 with IdP certificate Fernet-encrypted at rest
  • Org-required MFA toggle (Growth+); super_admin exempt to prevent platform lockout
  • SSO-only mode optionally enforced; org_admin retains break-glass password
  • Login rate limit: 5/minute per IP via slowapi

Session management

Every issued access token carries a unique jti. Sessions are tracked in active_sessions and can be revoked at two levels.

  • Soft revoke (user): revokes refresh token; access dies at JWT expiry (≤15 min)
  • Force logout (admin): revokes refresh + adds jti to Redis blocklist for immediate 401 on the next request
  • Blocklist check runs on every authenticated request (~0.1 ms; degrades gracefully if Redis is down)
  • last_active_at and current_jti updated on every refresh
  • Session listing surfaces every active session per user with IP / user-agent

Data isolation & multi-tenancy

All customer data is org-scoped at the row level. Cross-tenant data leakage requires a router bug, not just an auth bypass.

  • org_id column on users, vendors, evidence, audit logs (reports/reviews/attestations inherit via vendor FK)
  • Every router query joins through the JWT-derived org
  • Vendor uniqueness composite-keyed on (org_id, name)
  • Per-org Anthropic / Gemini LLM keys, encrypted with Fernet
  • Cross-org operations require super_admin (explicit, audited)

Application hardening

Defense-in-depth at the application layer beyond auth.

  • TLS 1.3 + HSTS via Let's Encrypt (auto-renew daily via certbot.timer)
  • Standard security headers: CSP, X-Frame-Options, X-Content-Type-Options
  • PDF and DOCX uploads validated by magic bytes (not just MIME)
  • File-size limits on uploads; rejected with explicit error
  • Backend bound to 127.0.0.1; only nginx talks to it
  • CORS allowlist controlled by ALLOWED_ORIGINS env (no wildcards)
  • All mutating actions emit append-only audit-log events

Deployment models

Three deployment options reflect three trust postures. Choose the one your security team can defend.

  • Cloud SaaS (default): multi-tenant on socbot.cyberblacksec.com, US-EAST hosting
  • Private deploy: single-tenant either on our infrastructure or in your AWS / Azure / GCP VPC (+$18–24K/yr)
  • On-prem / air-gapped: customer-hosted, full source escrow option (+$36K/yr including installation and first-year support)
  • Self-host pattern uses Docker images; no public internet egress required in air-gap mode

Backup, disaster recovery, and verification

Two-layer backup with weekly automated restore verification. The verification is what auditors actually look for.

  • Nightly local backup: pg_dump (gzip-9), uploads tarball, gpg-AES256 encrypted .env, SHA-256 manifest
  • Off-host nightly push to Cloudflare R2 in a separate cloud account
  • Weekly automated restore test: pulls latest dump from R2, restores into isolated DB, dynamically enumerates all tables, row-count parity vs live
  • Restore script verifies SHA-256 manifest before touching the live DB
  • Code archive weekly to R2 with .env / secrets / build artifacts excluded
  • Retention: 14 days local, governed by R2 bucket lifecycle off-host

Audit logging

Every action that changes state writes an append-only audit event.

  • Append-only audit_logs table with category (user / info / security / error / processing / ai) and severity
  • All major mutating actions emit events: auth, user mgmt, report upload / analyze, evidence ops, reviews, attestations, annotation changes, OIDC / SAML config, sessions, vendor import
  • Annotation activity feed tracks old → new value for every reviewer override
  • Admin UI at /audit-logs with filters + pagination
  • Audit data retention configurable on Enterprise (default 1 year)

LLM key posture (BYOK)

Every org configures its own Anthropic and Gemini API keys. We never proxy LLM calls through a shared key.

  • Anthropic + Gemini keys stored Fernet-encrypted in organizations.settings
  • Decrypted in-memory only at call time; never logged
  • Prompt-cache locality: cache lives in the customer's Anthropic account, not ours
  • Customer controls model selection, prompt-cache spend, and rate limits
  • Key rotation is a one-screen settings change with no service interruption
  • Air-gap deployments support local-model alternatives via Ollama (Enterprise add-on)
Sub-processors

Who else touches the data

A complete list of third parties involved in processing customer data on Cloud SaaS. Private deploy and on-prem customers can remove most of these from the picture.

Sub-processorRoleRegionScope of data
Anthropic (Claude API)LLM provider for the 5-phase analysis pipelineUSCustomer keys (BYOK). Prompts include SOC report text + system prompts. Customer-owned account; we never see the prompts or responses.
Google (Gemini API)Alternative LLM providerUS (global routing)Customer keys (BYOK). Same posture as Anthropic — customer-owned account.
DigitalOceanPrimary cloud hosting (Cloud SaaS only)US-EAST (NYC3 region)Hosts the application server, PostgreSQL, Redis, and uploaded files for Cloud SaaS customers. Private deploy customers host their own.
Cloudflare R2Off-host encrypted backup storageAuto (US-bound)Encrypted database dumps, file backups, and the gpg-encrypted .env. Bucket lives in a separate cloud account from primary hosting.
Let's EncryptTLS certificate authorityGlobalIssues and auto-renews TLS certs for the customer-facing domain. No customer data ever transits.
SendGrid / SMTP (configurable)Transactional email deliveryConfigured per-tenantUser invites, password resets, attestation notifications, audit-committee briefings. SMTP host is org-configurable; can be customer's own Microsoft 365 / Google Workspace.

Procurement asking deeper questions?

We have a pre-filled response to the standard SIG / VSAQ / CAIQ questionnaires. Send your security team straight to us — we’ll turn it around in two business days.

Email security@