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 our latest internal audit reports under NDA.
TLS 1.2+ in flight (1.3 preferred) · secrets and backups encrypted
All HTTP traffic over TLS 1.2 or later (TLS 1.3 preferred) with HSTS. Per-org LLM keys, SSO client secrets and SAML IdP certificates are encrypted with Fernet (AES-128-CBC + HMAC-SHA256) under a separate ENCRYPTION_KEY. Database dumps and file backups are gpg AES-256 encrypted before they leave the host. The live database is bound to localhost with no public port; ask us about disk-level encryption for your deployment tier.
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).
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), assigned per user by an org admin.
Internal security and privacy audits · third-party assessment planned
The product undergoes internal security, privacy and client-readiness audits with dated findings and remediation reports (most recently September 2026), available under NDA on request. We do not yet hold a SOC 2 report or an external penetration-test report; an independent third-party assessment is planned and we will publish its status here when it is engaged.
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; 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; per-account lockout for 15 minutes after 10 failed attempts from two or more addresses
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 LLM provider keys (Anthropic, Azure OpenAI, OpenAI), encrypted with Fernet
- Cross-org operations require super_admin (explicit, audited)
Application hardening
Defense-in-depth at the application layer beyond auth.
- TLS 1.2+ (1.3 preferred) + 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 logs are retained for the life of the organization's account and are append-only: a database trigger blocks updates and deletes (see the data retention policy)
LLM key posture (BYOK)
Each org configures its own LLM provider key (BYOK). An org that has not added a key yet, typically during a trial, runs on a platform-managed Anthropic key until it does. In either mode we do not read prompts or responses; the provider's API data-use terms apply.
- Anthropic, Azure OpenAI and OpenAI keys stored Fernet-encrypted in organizations.settings
- Decrypted in-memory only at call time; never logged
- Prompt-cache locality: with BYOK, the cache lives in the customer's provider 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)
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-processor | Role | Region | Scope of data |
|---|---|---|---|
| Anthropic (Claude API) | Default LLM provider for the 5-phase analysis pipeline | US | Prompts include SOC report text, evidence text and, for scanned documents, page images. Customer-owned account when BYOK is configured; otherwise a platform-managed key under Anthropic's API terms. We do not read prompts or responses. |
| Microsoft (Azure OpenAI Service) | Optional LLM provider, only if your org selects it | Customer's Azure region | Same data as Anthropic. Customer-owned Azure resource and key (BYOK). |
| OpenAI (API) | Optional LLM provider, only if your org selects it | US | Same data as Anthropic. Customer-owned account and key (BYOK). |
| Cloudflare (Turnstile) | Bot protection on the public request-access form | Global | Visitor IP address and browser signals are sent to Cloudflare to verify the challenge. No customer documents. |
| DigitalOcean | Primary 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 R2 | Off-host encrypted backup storage | Auto (US-bound) | Encrypted database dumps, file backups, and the gpg-encrypted .env. Bucket lives in a separate cloud account from primary hosting. |
| logo.dev and Google (favicon service) | Vendor logo lookup for the vendor directory | US / Global | Only the vendor's public website domain, as entered by your org, is sent server-side to fetch a logo image for display. No customer documents and no personal data. Enabled by default; an org admin can switch it off. |
| Let's Encrypt | TLS certificate authority | Global | Issues and auto-renews TLS certs for the customer-facing domain. No customer data ever transits. |
| SendGrid / SMTP (configurable) | Transactional email delivery | Configured per-tenant | User invites, password resets, attestation notifications, audit-committee briefings. SMTP host is org-configurable; can be customer's own Microsoft 365 / Google Workspace. |
| Microsoft (Microsoft 365 / Graph) | Optional transactional email provider | Customer's Microsoft 365 tenant | Used only when the instance is configured to send mail through Microsoft Graph. Same content as the SMTP / SendGrid row. |
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.