Account and security
Target reader: developers managing their own account and operators maintaining the local evaluation stack.
Minimal example
/register → /verify-email → /login → /settings/account
Register and verify
Open Register in the Console, choose a 12–200-character password, and submit your email and display name. The account remains pending_verification and cannot access tenant data until you enter the eight-digit email code and your registered password. Verification changes it to active; sign in afterwards. Codes are entered in a form and sent in the request body, never a URL. Passwords and codes are not persisted by the browser.
A code expires after 15 minutes and allows five failed attempts. A replacement invalidates the previous code. You can request another after 30 seconds, up to ten issues per purpose per hour. Duplicate registration keeps the original pending account and password. If you do not know that password, use password recovery, then request a fresh verification code.
Registration and code-request responses say only that a request was accepted; they do not disclose account existence or guarantee delivery. A mail connection failure is shown as unavailable, while the pending account is retained. Check your inbox and use resend after recovery. A recipient-level rejection cannot be distinguished from an ineligible address. Verification and reset codes cannot be interchanged or replayed.
Passwords and sessions
Use Forgot password to request a reset code. Enter the code and a new password on Reset password. Successful reset changes the password and revokes every previous session in one transaction; it does not sign you in automatically or activate a pending account. If email verification is still required, request a new verification code next.
Settings → Account and security provides password change and Sign out all sessions. Password change requires the current password and signs out every session, including this tab. Ordinary Sign out revokes only the current session. A failed sign-out remains visibly unconfirmed and can be retried; the UI does not claim success while retaining a usable server session.
Every Admin request validates the current account and its real session. Revoked, expired, disabled and deleted sessions are denied. Restore never revives old sessions. Previously issued attachment download URLs retain their existing short expiry; account logout does not recall already downloaded copies.
Delete an account
The same settings page offers permanent account deletion with current-password confirmation and an explicit checkbox. If you are the last active owner of an organization, first promote another active, verified member to owner in its Members page. G4 does not offer organization closure as a substitute.
Deletion removes your email, name, password, memberships and current feedback assignments, invalidates sessions and account codes, and revokes pending invitations created by or addressed to you. Invitation history clears your recipient mailbox. Shared projects, their keys, feedback, attachments, comments and necessary audit history remain. An anonymous UUID tombstone preserves those references, shown as “Deleted user”. This is not deletion of all shared business data or backups; that lifecycle is separate. A deleted account cannot be restored.
Local mail and operator maintenance
Mailpit captures local SMTP at port 1025; read mail at http://localhost:8025. No external relay or production mailbox is used. SMTP connections and operations are bounded. Production delivery and domains remain a later operational acceptance step.
Only a database operator may use the scoped maintenance command. Supply ACCOUNT_MAINTENANCE_DATABASE_URL privately in the environment, then run from the Admin API repository:
: "${ACCOUNT_ID:?set the target account UUID}"
go run ./cmd/accountctl --user-id "$ACCOUNT_ID" --action disable
go run ./cmd/accountctl --user-id "$ACCOUNT_ID" --action disable --apply
go run ./cmd/accountctl --user-id "$ACCOUNT_ID" --action restore --apply
The first command is a dry run. Repeated operations are idempotent, act on one account, and report IDs/status/counts without credentials or identity fields. Disabled accounts lose every session. Restore returns verified accounts to active and unverified accounts to pending; users must sign in again. Tenant administrators cannot globally disable another account. system_admin still grants no tenant access without membership.
Bootstrap is only for an empty account database and creates a pending operator identity. Existing identities, including tombstones, prevent automatic recreation on restart. Local demo seeds are separate, explicitly verified synthetic fixtures. Old Alpha accounts and business data are not migrated; use a fresh current-schema dataset. The fixed G3 archive remains historical evidence; use the current SDK download with these servers.
Registering the same email after deletion creates a new UUID and requires verification again; it inherits no sessions, memberships or invitations. The operator output sole_owner_organizations counts organizations without another usable owner. Operators may temporarily disable a sole owner to freeze access; membership remains for restoration and a new login. Account deletion and membership demotion still require a usable owner to remain.
Common mistakes
- Do not put a code, password, JWT or invitation token in a link or log.
- Do not treat request acceptance as inbox delivery or password reset as a new login.
- Do not confuse removing tenant membership with global disable, or personal deletion with deleting shared projects.
- Do not attempt to restore deleted accounts or reuse old Alpha tokens/data.
Next step
Continue with the Developer Console or inspect the Admin API.