crusaderbase

Security

Last updated: 2026-05-23

CrusaderBase runs AI agents against operating data customers rely on — orders, deductions, invoices, creator outreach. Customers entrust us with credentials and historical records. This page describes the controls in place today and the ones we are actively building. We update it as posture changes.

Questions or vulnerability reports can be sent to dillon@enjoynotbeer.com. See responsible disclosure below.

Tenant isolation

Every customer organization ("tenant") has its own isolated logical workspace. Cross-tenant reads are prevented at three layers:

  • Database role separation. The application connects to Postgres as a non-superuser role (nb_app) that cannot bypass row-level security. A separate nb_admin role exists for migrations and platform-wide reads, never for request handling.
  • Row-level security on every tenant-scoped table. Postgres enforces tenant_id = current_setting('nb.tenant_id') on read and write. A tenant context is set at the start of every request from the authenticated session; queries cannot return rows from a different tenant.
  • Application-layer query helpers. All data access flows through withTenantClient(tenantId, …) or withAdminClient(…) wrappers. Direct legacy queries are blocked at CI by a ratchet test; the count of legacy callsites is 0 on main.

Connections (Gmail, EDI partners, SFTP, API keys) inherit the tenant boundary. Per-user binding controls let admins decide whether a connection is private to its creator or shared tenant-wide; sharing changes are audited.

Authentication and access control

  • Sign-in via Clerk. Customer users authenticate through Clerk, which handles password hashing, session management, account recovery, and brute-force protection.
  • Multi-factor authentication for platform admins. Every account with platform-admin scope is required to complete a second factor (passkey or authenticator-app TOTP) within the last 30 days. Sessions without a valid second factor are rejected at the application layer.
  • Role-based authorization. Inside each tenant, users hold one of four roles — owner, approver, viewer, or tenant_admin. Mutating actions require the appropriate role; reads of other users' private resources by a tenant admin write an admin_override audit row.
  • Platform admins are listed in a database table (core.platform_admins), not in source code or environment variables. Adding or removing a platform admin is audited.

Encryption

  • In transit. TLS 1.2+ for all customer traffic. HSTS is enabled on the production domain.
  • At rest. Application database and backups are encrypted at rest by Supabase (AES-256). Object storage in AWS S3 uses server-side encryption (SSE-S3 or KMS, depending on bucket).
  • Secrets.Per-tenant credentials (refresh tokens, EDI passwords, API keys) live in AWS Secrets Manager under tenant-scoped key paths; database rows store only the secret's ARN, never the value. Secrets are pulled at request time, never logged, and redacted by the application error sink before forwarding to Sentry.

Data lifecycle

  • Customer export.An authenticated tenant owner can request a full export of their tenant's data via the platform's tenant-export endpoint. Output is a zipped archive of every table the tenant has rows in, with secrets redacted.
  • Customer-initiated deletion.A tenant owner can hard-delete their tenant. Deletion runs row-level removal across every tenant-scoped table, blocks pending pending destructive operations, and writes an audit row. Backups are retained per the rotation cadence below; new backups taken after deletion do not contain the tenant's rows.
  • Retention.Production database backups are retained at Supabase's default cadence (7-day rolling point-in-time recovery window plus daily snapshots). Daily audit-log exports to S3 follow a 30-day Standard, 60-day IA, 640-day Glacier IR lifecycle (730 days total).

Audit logging

Every state-changing action — connections being created or shared, secrets resolving, conversations being read across users, tenant data being exported or deleted, platform-admin actions — writes a row to core.audit_log. Audit rows include the actor, target, action, before/after state, and structured metadata.

  • Append-only at the database role.The application's database role has INSERT but not UPDATE or DELETE on the audit log. A separate test verifies attempted modification fails.
  • Daily immutable export.A scheduled job writes the prior day's audit rows to a versioned S3 bucket; the bucket has server-side encryption and lifecycle rules ensuring long-term retention.
  • Independent error monitoring via Sentry, with a scrubber that strips credentials, OAuth tokens, and other sensitive values before any event leaves the application. The scrubber has a regression test that injects synthetic secret patterns and asserts none reach Sentry payloads.

Backups and disaster recovery

  • Daily snapshots. The production database has both Supabase-native point-in-time recovery and an independently scheduled pg_dump to a private, encrypted, versioned S3 bucket. The script and runbook live in the repository under scripts/run_pg_dump_to_s3.sh and DISASTER_RECOVERY.md.
  • Restore drill. A full restore from S3 into a scratch Supabase project has been executed end-to-end. Future drills are scheduled on a recurring cadence.
  • Targets. Recovery-point objective: ≤ 24 hours for daily snapshots, ≤ 5 minutes within the rolling point-in-time window. Recovery-time objective: ≤ 4 hours for full database restore.
  • Scope and limitations. These backups cover the production database. Files stored in object storage (uploads, attachments, and generated documents) are not included in the database snapshots; they are retained separately under the storage provider's own durability and versioning. A file permanently deleted from object storage cannot be recovered from a database backup, so treat destructive deletes of stored objects as irreversible.

Vulnerability management

  • Dependency scanning. Every pull request runs npm audit with a hard CI gate. Known high or critical CVEs block merge.
  • Static analysis. The codebase is fully typed (TypeScript strict mode) and linted on every PR. A suite of security-specific ratchet tests covers authentication coverage, cron-secret coverage, audit-log append-only, scrubber completeness, and forbidden direct-query patterns.
  • Adversarial test suite. A dedicated tests/security/ directory includes intra-tenant user isolation probes, cross-tenant access probes, chat-tool fuzzers, upload fuzzers, and rate-limit coverage tests. New probes are added as new threat surfaces ship.
  • Patch SLA. Security patches to dependencies are reviewed and merged within 7 days of publication for high/critical CVEs.

Incident response

We maintain a written incident-response runbook covering detection, containment, eradication, recovery, and post-incident review. Customers affected by a confirmed security incident receive notification by email within 72 hours of confirmation, per the terms of our Data Processing Agreement.

Responsible disclosure

We welcome reports of suspected vulnerabilities from security researchers and customers. To report a vulnerability:

  • Email dillon@enjoynotbeer.com with a description of the issue and steps to reproduce.
  • Please do not publicly disclose the issue before we have had a reasonable opportunity to investigate and remediate (generally 90 days from initial report).
  • We will acknowledge receipt within two business days and provide an initial assessment within five business days.
  • Testing must not access, modify, or destroy data belonging to other customers, and must not degrade service for other customers. Denial-of-service testing is out of scope.

We do not currently operate a paid bug-bounty program. Good-faith reports receive a written acknowledgement.

Subprocessors and contractual terms

  • Subprocessor list — every third party that processes customer data on our behalf, with the data category and processing location. Customers receive at least 30 days' notice of changes.
  • Data Processing Agreement — controller/processor terms, breach notification, and the Standard Contractual Clauses for international transfers.
  • Privacy policy — what data we collect, why, and customer rights.

Compliance roadmap

We are pre-revenue on a paid commercial plan and have not yet undergone a third-party audit. The current trajectory:

  • SOC 2 Type 1 — planned once we reach ≥ 3 paying customers. The control framework is being built against SOC 2 trust-services criteria today so the audit window reflects steady-state operations.
  • External penetration test — annual cadence once a paid commercial plan is live. Findings are remediated before customer onboarding.
  • SOC 2 Type 2 and ISO 27001 — deferred until Type 1 is complete and we have ≥ 12 months of operational evidence.

Contact

For security questions, vulnerability disclosures, or questionnaires: dillon@enjoynotbeer.com.

CrusaderBase is operated by Not Beer Inc.. We update this page as posture changes; refer to Last updated at the top.