Thalix VaultDocumentation
Browse documentation
Operators
publishedimplementedEdit this page

Runbook: user offboarding and deactivation

Deactivate

tv admin user deactivate person@example.com

Requires admin/global_admin, and follows the same hierarchy rule as re-roling (see Users, roles, and groups): a global_admin may deactivate anyone but themselves; an admin may deactivate only a user-role member, never a fellow admin, and never their own account.

Deactivating the sole active owner of a group that still has other active members is refused with GROUP_OWNER_DEACTIVATION_BLOCKED until ownership is transferred (tv group transfer) or an administrator recovers it — see Group owner recovery below.

What deactivation does, immediately, in one transaction

deactivate_identity (supabase/migrations/20260820163000_mvp004_identity.sql) does all of the following atomically:

  1. Flips the subject's profile status and organization-membership status to deactivated.
  2. Deletes their auth.sessions rows and auth.refresh_tokens rows — the browser (Supabase-provider) session is revoked immediately, not just left to expire.
  3. Records one identity.deactivated audit event with the acting administrator, the subject, and the organization.

What deactivation does not do directly — and why it doesn't need to

It does not walk the CLI's cli_access_tokens table and revoke each device token individually. Instead, every CLI-authenticating RPC (authenticate_cli_access_token and everything built on it) re-checks the caller's profile and organization-membership status live, on every call. A deactivated account's existing tv_ bearer token therefore stops working on its very next use — tv whoami, tv file find, everything — with ACCOUNT_DEACTIVATED, exactly as if the token had been individually revoked. There is no window where a deactivated user's CLI session keeps working because "revocation hasn't caught up yet."

What deactivation deliberately preserves

  • Ownership. Files owned by a deactivated user keep their owner_user_id unchanged. Nothing is reassigned or orphaned. An administrator can still reach that user's files via --admin-reason (see Audit and administration), and any existing grant a deactivated user created stays valid on its own terms until someone revokes it — deactivating the grantor does not retroactively revoke grants they already made.
  • History. Every audit event, metadata revision, and content version the user is attributed to remains exactly as it was. Deactivation is a status flip, never a deletion.
  • The account row itself. There is no delete-user command. Re-activation is not currently exposed either (tv admin user deactivate has no inverse command) — if a deactivated user needs to return, that is presently a database-level exception, not a supported tv workflow; note this gap for the requester rather than improvising an unaudited fix.

Group owner recovery

tv admin user deactivate refuses with GROUP_OWNER_DEACTIVATION_BLOCKED when the subject is the sole active owner of a group that still has other active members. An owner must run tv group transfer <group> <email> first, handing sole ownership to another active member in one atomic step, before deactivation can proceed.

If a group is ever left with zero active owners, it enters an explicit recovery state (needsOwnerRecovery: true in tv admin group list). An administrator resolves it with:

tv admin group transfer <group> <email>

This promotes an existing active member to owner without demoting anyone else — it never creates membership and never applies to a group that already has an active owner. Both the deactivation block and the recovery transfer are audit-logged.

Verify

tv admin user list
tv admin audit list --target-type user --target-id <user-id>

Confirm the member now shows deactivated status, and that the identity.deactivated event appears with the correct actor and correlation ID for your offboarding record.

Continue with Users, roles, and groups or Incident investigation.