Trust

Security & privacy posture

Summary aligned with our internal security documentation. For contractual artefacts or questionnaires, contact us through the sales inbox.

Authentication

Keycloak OIDC handles sign-in; BayOps does not store user passwords. NextAuth manages sessions with JWTs (no database session table). Sessions use a 24-hour absolute lifetime. Optional app-layer TOTP two-factor authentication can be enabled per user after Keycloak sign-in.

Authorization

Roles such as Owner, Manager, Estimator, and Reception map to a practical hierarchy enforced in API routes. Tenant context keeps organization data partitioned.

Transport & secrets

HTTPS is enforced in production (Strict-Transport-Security). For non-local database hosts, connections use TLS and the app verifies that the database URL requests SSL in production. Secrets (database URL, NextAuth secret, Keycloak client secret, field encryption keys, OCR service keys) live in host environment configuration—not in source control.

HTTP security headers

Next.js config sets X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy, and a tightened Content-Security-Policy (production script-src is 'self' only—no unsafe-inline). Strict-Transport-Security applies in production.

Edge middleware & abuse protection

Middleware assigns request IDs and enforces Redis-backed rate limiting via Upstash in production (configure UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN). Development may fall back to in-memory limits. Non-public API routes require a valid session JWT at the edge in addition to per-route authorization checks.

Document storage (Supabase)

The documents bucket is private. Uploaded blobs store an internal path—no long-lived public URLs. Authorized list/detail flows mint short-lived signed URLs for viewers who are allowed to see the underlying file.

Field encryption (application layer)

Selected columns are protected with AES-256-GCM via our field encryption helper and Prisma extensions—examples include customer policy numbers, certain vehicle identifiers, two-factor backup material, sensitive OCR payloads, and integration tokens such as QuickBooks refresh secrets. Production deployments require FIELD_ENCRYPTION_KEY (64 hex characters or 32-byte base64); the application refuses to start without it. New ciphertext uses a versioned prefix to support future key rotation. Operational migrations apply when enabling encryption on existing plaintext.

Audit logging

Tenant-scoped audit entries capture entity-level changes for accountability during reviews and investigations.

OCR ingestion

Size limits and MIME allowlists gate uploads; production error responses stay generic while development environments may surface richer diagnostics.

Payments / PCI

Payment card data is not stored in BayOps. Card-present or online flows should use a compliant processor such as Stripe so sensitive PAN data stays on the processor's infrastructure.

Responsible disclosure

If you discover a vulnerability, please report it via our contact form (select the security topic if available) or your contractual security channel. Machine-readable contact hints live at /.well-known/security.txt.

Data ownership & privacy

You can export operational data for business continuity. We do not sell your customer lists. Read our privacy policy for data processing details.

This page is a summary—not a warranty. Review with counsel for regulated use cases and refer to docs/compliance/security.md for the engineering source of truth.

Questions about our security posture?

We are happy to walk through controls, data flows, and questionnaires with your team.