Strata PlatformDocs

Organization deletion

Permanently delete your organization and every member's data, with a Kronisys approval gate and a 30-day grace window.

The deletion request lives at Organization → Profile → Delete organization (the last row of the Account group, at the bottom of the section). Submitting the request requires the Suspend organization permission (canSuspendOrg). Canceling a pending or scheduled deletion requires Manage organization settings (canManageOrgSettings).

The two-signal design

A single click cannot delete your organization. Two signals must both be present and the grace window must elapse:

  1. Customer request — an admin with the Suspend organization permission submits the request from the Delete organization row in Organization → Profile. Stored as deletion_requested_at on your organizations row.
  2. Operator approval — a Kronisys Inc. operator runs node server/tools/approve-org-deletion.js <org_id> --days=30 after reviewing your request. Stored as deletion_scheduled_at.

Until both timestamps are present and deletion_scheduled_at has passed, the sweeper (cleanupScheduledOrgDeletions, runs every 6 hours) does nothing. Your organization stays fully operational throughout.

This design protects against three failure modes:

  • Accidental delete — a tired admin can't nuke the org with one button click.
  • Social engineering — a compromised admin account cannot fast-track destruction.
  • Compliance theatre — the operator review forces a real "is this the right call" pause and a paper trail.
Key

There is a fourth backstop in the sweeper itself: it refuses to purge an organization that is still paying. Even with both timestamps set and the date passed, an org whose billing status is entitled (active, past_due, action_required, trialing, or provisioning) or that has any non-terminal Stripe subscription is skipped, because a deletion cannot be undone. The customer-initiated path is unaffected — an approved request has the subscription canceled first — but a scheduling mistake against a live, paying org cannot silently erase it.

Requesting deletion

  1. Open Organization → Profile.
  2. Scroll to the Account group at the bottom of the section; Delete organization is its last row. Without the Suspend organization permission the row shows Needs the "Suspend organization" permission. Ask an owner. in place of the button.
  3. Click Request organization deletion….
  4. A modal opens with two fields:
    • Reason for deletion (optional) — free-text. Useful for the operator's review.
    • Type <your org name> to confirm — you must type the org's display name (or domain if no display name) exactly. The Request deletion button stays disabled until the typed text matches.
  5. Click Request deletion.

What happens:

  • The org row gets deletion_requested_at = GETUTCDATE(), deletion_requested_by = <your user id>, and deletion_request_reason = <your reason>. Idempotent — re-submitting just refreshes the reason.
  • An audit entry is written: org.deletion_requested with the typed-confirmation org name and the reason in details.
  • An email goes to support@kronisys.com (or OPS_NOTIFY_EMAIL) summarizing the request and instructing the operator how to approve.
  • The Delete organization row under Organization shows "Deletion requested", the time of the request, "awaiting Kronisys Inc. approval", and your reason.

Operator approval

A Kronisys operator reviews the request, contacts the requester to confirm intent if needed, then runs:

node server/tools/approve-org-deletion.js <org_id> --days=30

This sets deletion_scheduled_at = now + 30 days and writes deletion_approved_by. The Delete organization row now reads:

Deletion approved by Kronisys Inc. Your organization and all data will be permanently deleted on <date> (N days from now).

On the scheduled date itself it reads "Deleting today (0 days from now)."

The grace window can be any number of days — 30 is the default. Operators may extend on request.

Every active admin is emailed when the deletion is approved. Subject: [Strata] Deletion of <organization> approved — scheduled for <date>. The email gives the scheduled date, the days remaining, and who approved it, and explains how to cancel.

Canceling a deletion

You can cancel until the deletion runs: before approval, throughout the grace window, and on the scheduled date itself until the sweeper (every 6 hours) purges the organization. There are two distinct cancel buttons depending on the state:

  • Cancel deletion request — before operator approval. Clears deletion_requested_at, deletion_requested_by, deletion_request_reason.
  • Cancel scheduled deletion — after operator approval, until the deletion runs. Clears the above plus deletion_scheduled_at and deletion_approved_by. It is the section's filled button, to make the cancel path obvious (when the row above offers Lift suspension, that is the filled one and Cancel is a plain button).

Both paths hit POST /api/admin/org/cancel-deletion, require canManageOrgSettings, and write an org.deletion_canceled audit entry. After cancellation, the Delete organization row goes back to the Request organization deletion… button.

You cannot reverse the deletion once the sweeper has run.

A deletion that started automatically because the subscription ended has no Cancel button: reactivating the subscription is what stops it, and the row links to Billing.

The 30-day grace window

During the grace window:

  • Every member can sign in and use Strata normally.
  • Chats, agents, scheduled runs continue exactly as before.
  • The Delete organization row shows the date and the days left to every admin with Manage org settings, so they know the clock is running.
  • You can cancel at any point.

Use the window to:

  • Run a final admin data export of every user's conversations, messages, and settings.
  • Export the audit log as CSV for your compliance archive.
  • Notify members so they download anything they want to keep.

What is irreversibly removed

When cleanupScheduledOrgDeletions runs after the scheduled date, the sweeper hard-deletes everything in one verified transaction — child rows before parents, each statement run individually so a failure names the exact table and aborts the whole purge rather than leaving the org half-alive, and the organizations row is read back as gone before the deletion is reported as done:

  • The organizations row and every users row in the org.
  • All per-user data: sessions, user_settings, user_extension_permissions, user_db_access, user_skills, extension_tokens, connection_memory, personal db_connections, files, conversations, messages_archive, messages_cold, scheduled_agents, agent_runs, and the user's activity_log rows.
  • All group structure: org_groups, org_group_members, group-to-role bindings, and group spend caps.
  • All org-scoped configuration and content: org_roles, org_db_connections, pending_invites (and preconfigured invites), api_keys, api_key_webhooks (and their delivery records), org_agent_templates, custom connectors (mcp_servers, with their stored credentials), every member's connector opt-ins and sign-ins (mcp_user_connectors, mcp_user_oauth) and any connector sign-in that was started but never finished (mcp_oauth_flows), announcement templates and drafts, per-model allowances, usage ledgers, inbox messages, support-desk conversations and tickets, and the Knowledge Base tables (kb_sources, kb_documents, kb_chunks).
  • The organization's audit log rows — both the org's own rows and any failed-sign-in rows attributed to its domain.
  • The billing mirror (billing_customers, billing_subscriptions, billing_invoices, billing_payment_methods, billing_events) and any self-serve signup records. Before purging, the sweeper cancels the organization's Stripe subscriptions; if that cancel fails, the whole purge is aborted and retried on the next sweep, so a live subscription can never keep billing a deleted org.
  • After the transaction commits, the sweeper reaps the matching cold-stored message blobs, uploaded-file blobs, and data-export ZIPs (admin and per-user) from Azure Blob Storage.

There is no soft-delete. There is no recovery. Make sure you have run your final exports.

Alert

Your audit log is erased with the organization — a right-to-erasure request leaves nothing behind. The only record that survives is a single org-less org.hard_deleted entry (written with a system actor and no org_id) so the deletion itself stays in the platform compliance trail; it does not contain your log's contents. Export the audit log before the scheduled date if you need it in your own archive.

Final-export recommendations

A complete final export usually means:

  1. Admin data export for every active user (Organization → Profile → Account → Export organization data…, range = "All time"). Email includes a 24-hour signed download link.
  2. Audit log CSV (/admin/audit → Export). Capped at 50,000 rows; if you have more, narrow the date range and export in chunks.
  3. Individual user notice so people can run their own personal data export before the date.

Save all three to your compliance archive before the date passes.

What can go wrong

Error / symptomWhat it means
Type the organization name "<name>" exactly to confirm.The text you typed in the confirmation field does not match your org's display name or domain. Type it literally.
Org not foundThe org row was already deleted by another deletion request that completed.
Permission required: canSuspendOrgYour admin role lacks the Suspend organization permission needed to request deletion.
Permission required: canManageOrgSettingsYour admin role lacks the Manage organization settings permission needed to cancel a request.
Request submitted but no approval after several business daysEmail support@kronisys.com directly. The OPS notification mail may have bounced.
No Cancel button on the Delete organization rowThe deletion started automatically because the subscription ended; reactivate the subscription in Billing to stop it. A requested or approved deletion keeps its Cancel button until the deletion runs.
You cancel after approval but before the date and members lose access anywayA different action (admin disabled, role demoted) is responsible. Check the audit log.

See Admin data export for the final export workflow, Audit log for the deletion-request audit trail, and Security overview for the broader retention and erasure model.

Related