Tenant Lifecycle
What this covers / who it's for. How a workspace comes to life and where it can go: the self-service registration ladder, the KYB/KYC verification journey, the workspace status machine, and the orthogonal compliance freeze/closure overlay. Includes the honest gaps — what the lifecycle does not yet do automatically.
The headline: a tenant exists before any KYB
A business self-registers and gets a working workspace immediately — the tenant, its first user (the owner), and a live login all exist before any business verification has been submitted, let alone approved. Verification (KYB/KYC) is a journey the workspace runs from inside the product, not a gate in front of the door. What an unverified workspace can actually do is bounded by permissions and entitlements, not by being locked out.
The workspace status ladder
Every workspace carries exactly one lifecycle status. The onboarding rungs advance automatically as the owner completes each step:
| Status | Meaning | How it's entered |
|---|---|---|
pending_verification | Fresh registration; the owner's email is not yet verified | Self-service registration |
mfa_required | Email verified; the owner must enrol an MFA factor | Owner verifies their email code |
onboarding | Login fully secured; the KYB/KYC journey is open | Owner confirms their first MFA factor |
active | Fully operational workspace | Defined but not yet wired — see the gaps below |
suspended | Temporarily paused, data retained (e.g. monthly statements still generated) | Operational branch — no driver surface yet |
deactivated | Switched off; reactivation or offboarding are the only ways out | Operational branch — no driver surface yet |
offboarded | Terminal — the workspace has left the platform | Operational branch — no driver surface yet |
Illegal jumps are impossible: transitions are validated by a single state machine with one
writer (specifics: tenancy README).
The honest gaps (what is not automatic today)
- KYB approval does not activate the workspace. When the provider approves the KYB
application, the platform updates its local application record to
approved— and nothing else. Theonboarding → activetransition exists in the state machine, but no production code calls it; wiring activation to KYB approval is acknowledged future work, not implied behavior. - The operational branches have no driver yet.
suspended,deactivated, andoffboardedare fully defined (transitions validated, scheduled platform jobs respect them — e.g. a suspended workspace still gets monthly statements, and a workspace deactivated mid-month gets a final closing statement), but no operator surface or automated flow currently moves a workspace into them.
In practice the automatic ladder today runs registration → email verified → MFA enrolled →
onboarding, and stops there.
The verification journey (KYB + KYC)
Verification runs while the workspace sits at onboarding. It is provider-executed:
Stables collects and relays; the regulated rail decides. Full mechanics:
onboarding README.
- Requirements-driven, never hardcoded. The KYB checklist (fields, documents, minimums, per-individual requirements) is fetched live from the provider per country; the form the user sees is rendered from that answer. A new market's requirements need no product change.
- Documents are vaulted before they are forwarded. Stables captures its own encrypted copy of every uploaded document first, then forwards to the rail — the platform is never left without its copy (see Compliance & trust).
- Decisions arrive asynchronously. Submission returns quickly with a
pendingapplication; progression (processing,approved,rejected,requires_info) is driven by provider webhooks, with a reconciliation backstop if a webhook is missed. See Async by design. - RFIs (requests for information) are relayed by Stables. The provider never contacts the business directly. An RFI lands as a non-opt-out compliance notification to the tenant's onboarding owners, listing what is required; the user answers through the product (including further documents). Duplicate or out-of-date RFI webhooks are absorbed — the notice is sent exactly once.
- KYC (individual identity verification) is offloaded to Persona via the rail: the user triggers verification, Stables relays back a provider-hosted verification URL, and the outcome flows back on the webhook stream. Stables runs no identity verification itself.
- An application can be rejected (with failure reasons recorded) or flagged for enhanced due diligence; the business can submit again — a customer can hold multiple applications over time.
The compliance overlay — freeze & closure (orthogonal to status)
Separately from the lifecycle ladder, compliance can place an enforcement state on the
account. This is a compliance officer's action (step-up + recorded rationale), independent of
WorkspaceStatus — a workspace can be active and frozen. Specifics:
compliance README and
Compliance & trust.
| State | Can sign in? | Can act? | Reversible? |
|---|---|---|---|
| Normal | Yes | Yes (per permissions/entitlements) | — |
| Frozen | Yes — login still works | No — every authenticated request is refused with ACCOUNT_FROZEN (403), including reads; the app shows a frozen wall | Yes — unfreeze lifts it (and releases any deposits held during the freeze) |
| Closed | No — even login is refused with ACCOUNT_CLOSED | No | No — terminal. A closed account cannot be unfrozen, re-frozen, or reopened |
Freeze in V1 is whole-account only (asset- or address-scoped freezes are deferred, tracked
work). The distinct signals are deliberate product language: ACCOUNT_FROZEN tells the user
"temporarily locked, contact support"; ACCOUNT_CLOSED says "this relationship has ended".
Putting it together — what a user experiences per state
| Workspace state | Sign in | See data | Move money / act |
|---|---|---|---|
pending_verification | Owner only, into the verify-email flow | Minimal | No — verify email first |
mfa_required | Yes, into MFA enrolment | Minimal | No — enrol a factor first |
onboarding | Yes | Yes | Per permissions + entitlements; KYB journey open |
active | Yes | Yes | Fully, per permissions + entitlements |
| any + frozen | Yes | No (403 wall) | No |
| any + closed | No | No | No |