Crossdeck Docs
Dashboard

Workspace operations

Getting started 8 min read · Append-only record, reversible archive, one-way sandbox wipe

A workspace accumulates state: keys, members, rules, settings, and a few million events. This page covers the controls that manage that state at the workspace level — the audit log that records every change and who made it, the archive switch that stops ingestion without destroying anything, the sandbox wipe that does destroy something (on purpose, with a typed confirmation), and the production / sandbox partition those operations respect.

TL;DR

The audit log

The audit log is the workspace's immutable change record. Every state-changing action — a key rotated, a member removed, a setting flipped, an entitlement granted, a subscription event processed — appends one entry. Entitlement-affecting decisions are recorded regardless of outcome: applied, rejected, and no-op decisions all land, so the log can always answer "why does this customer have access?" — including when the answer is "we received the event and deliberately did nothing."

Append-only, by construction

Entries are keyed by event ID and written with a create-only operation — there is no code path that updates or deletes an audit entry. If the same action is somehow audited twice, the second write is discarded and the first record stands untouched. Nothing in the dashboard re-derives or reformats stored values either: every field renders verbatim as written.

Who, and where from

Every human-initiated entry captures four actor columns: the actor's UID, email, IP address, and User-Agent — taken from the authenticated request that performed the action, not self-reported. System-generated entries (a Stripe webhook processed, a scheduled job) record the system as the actor instead. The point is forensic: an audit log that says what changed but not who, from where can't settle the question it exists for.

Categories

All categories share one log; the dashboard filters by category. The full set:

CategoryWhat lands in it
securityAuth events, key lifecycle (created / rotated / revoked), sign-in and sign-out, PII allow-list edits.
settingsWorkspace settings edits — allowed origins, framework, app identity. Sandbox clears land here too.
memberTeam invite, accept, remove, role change.
billingTier transitions, payment method changes, ledger reconciliations.
errorError-issue lifecycle: resolved, assigned, ignored, priority overridden, commented.
workspaceProject-level lifecycle: rename, archive, business-model switch.
alert_rulesCustom alert rule created, updated, deleted.
catalogCatalog backfill triggers and mapping changes.
supportSupport ticket lifecycle.
migrationMigration discovery runs, backfill triggers, signal status flips.
manualManual entitlement grants and revokes from the dashboard.
railSubscription state changes, refunds, and disputes from Stripe, Apple, and Google — every rail decision, with its outcome (applied, no-op, rejected).

Reading it

The Audit log page in the dashboard gives you time ranges (24h / 7d / 30d / 90d / All), the category tabs above, and a free-text search across event IDs, actors, types, subscription and customer IDs, reasons, and metadata. Entries load 100 at a time with a cursor-paginated Load more. Clicking a row opens a detail drawer with the full record — identifiers, actor (email, UID, IP), the decision and its reason, both timestamps (when the action happened and when it was processed), and the raw metadata JSON.

Export produces a flat file with every stored column: event ID, category, type, actor email / UID / IP, rail, decision, derived signal, subscription and customer IDs, fingerprint, reason, metadata, and both timestamps in ISO 8601. The export contains exactly what the table shows under your current filters — same rows, all columns.

Archiving a workspace

Archiving stops a workspace without destroying it. It is the right tool for a product you're sunsetting, a workspace created by mistake, or anything you want out of the way but not gone.

Concretely, archiving does three things:

The archive itself is audited automatically — a workspace archived entry records the actor and timestamp, and a matching entry is written if the workspace is later unarchived (which restores ingestion by clearing the same flag the keys check).

The confirmation gate

Archiving requires typing the workspace's exact name. The dashboard checks it, and the server checks it again — trimmed, case-sensitive — before doing anything. A request that skips the dashboard cannot skip the gate. You must also be a member of the project, and archiving an already-archived workspace is rejected.

Reversible for 30 days.

Archive is destructive in spirit, recoverable in fact: an archived workspace can be restored within 30 days, after which the archived data is permanently deleted. Restore deliberately doesn't live next to the Archive button in the Danger zone — you don't put "undo destruction" alongside destructive actions.

Clearing sandbox data

Clearing sandbox data wipes every env=sandbox record from the workspace so you can start test runs fresh. Unlike archiving, this one is irreversible — the records are deleted from both storage layers, and there is no recovery window.

What gets deleted — everything tagged env=sandbox for the project:

What survives — everything that isn't a sandbox record:

The same gates as archiving apply: you must be a project member, and the workspace name must be typed exactly — verified on the server, not just in the dialog. When the wipe completes, the dashboard reports the counts back ("Wiped 1,847 events, 12 subs") so you can confirm what happened.

There is no undo.

Internal-traffic filtering and bot filtering are query-time views over data that's still stored. Clearing sandbox data is not — the rows are gone from both stores. If a test run produced data you want to keep, export it first.

Environments

Every record in a workspace — event, customer, subscription, purchase, entitlement — carries an env of production or sandbox. The two never mix: separate keys, separate webhooks, separate ledger. Sandbox events cannot contaminate production metrics.

The key decides the environment. Every app carries two publishable keys — a live key and a test key. An event ingested with the live key is production; the test key, sandbox. The environment is derived from which key the request presented at the door, never from a stored app setting — so there is no configuration state that can silently flip where your data lands. (Apps created before dual keys existed carry a single legacy key, and only there does the app's stored environment setting decide.)

The dashboard mirrors the same partition with the environment switcher in the top bar: Live · Production or Sandbox. Switching reloads the dashboard so every surface re-reads in the new environment — there is no half-switched state where one chart shows live data and another shows test data. Production is the default. The full story — test-mode rails, sandbox webhooks, when to use which — is in Sandbox vs production.