Account

The Account package gives your application's end users their own accounts, which are not Turn Zero accounts, without building identity infrastructure of its own. It covers account creation, sign-in, sign-out, sessions that last across visits, and access recovery. When the manifest declares the accounts service, the platform creates one end-user realm, the list of an environment's end users, for each environment the application has. An application with one environment has one realm, production's, and its testers sign in there, also during a local run. With a development environment added, a sign-in to the development realm never reaches production's users.

Use it when

Use Account when an application must recognize a person across sessions, protect personal data, or tie records to one end user.

Do not add it only to remember a local preference or an anonymous device. Those needs do not justify an identity service.

What it provides

  • Account creation and sign-in.
  • Sessions: creation, persistence, and sign-out.
  • Access recovery.
  • Verification of an end-user session from the application's backend, by either of the two paths in The session token and its verification.
  • The end-user identity that other packages, such as Billing, depend on.

The package stores no per-account settings. Keep application preferences in the Database package.

A test double ships at the package's testing subpath, @turnzero/account/testing. createAccountDouble takes the place of the accounts service behind the unchanged verification client. It signs users in and out in memory under a key pair of its own. Test your application locally shows it in use.

From version 0.16.0, the double rejects any accounts call whose address contains a NUL character (U+0000), or whose JSON body contains a NUL character or an unpaired UTF-16 surrogate. It returns 400 invalid_request before it reads the credential, as the platform does.

Availability

Version 0.17.1 is the package's current version, and list_library reports the version the platform publishes. The entry includes the testing subpath from version 0.10.0.

The package's entry contains the verification client makeVerifyClient and the session-token module it imports, compiled in the entry's lib/ folder as the npm package @turnzero/account. It also contains the package's product statement, its detailed requirements for sessions, verification, passkeys, and emailed-code sign-in, and its integration guide. An application on version 0.9.0 or later can use the local verification path described below. An application that passes neither the key set nor the router's header keeps using the verification route.

From version 0.17.0, the platform that operates the package names the sign-in method a passkey speeds up. Turn Zero Cloud names the emailed code: it offers a passkey right after a sign-in by emailed code, and registers one only for a user who holds that sign-in. The passkey change asks nothing of your application's code.

Attaching or removing a passkey emails every verified address of the end user's account, in every realm. The one exception is a passkey registered when the platform offers one right after the sign-in that creates the account. For seventy-two hours, the user can undo the change from any sign-in method it left in place, after a fresh sign-in. Manage end users states when a notice is sent and how a passkey the device no longer has is removed.

Billing depends on Account. Verifying an end user explains how a backend verifies a session. Manage end users explains the realm's configuration and its end-user actions.

The session token and its verification

A signed-in end user has one cookie on the application's own hostname, __Host-turnzero_cloud_realm. Its value is a session token of the form turnzero_cloud_usr_1.<payload>.<signature>, signed with the realm's own Ed25519 key. The token lives one hour. When it expires, the serving router gets a fresh token for the same session from the accounts service, so the session outlives the token and your code does nothing.

Install the client as Use the library shows: copy the entry into app/lib/account/, declare the dependency as file:lib/account, run npm install, and import makeVerifyClient from @turnzero/account. Install @types/node if your application type-checks against the client's declarations, because they import Node's built-in modules. The token's form and its verification order live in the same package's lib/session_token.js, which the client imports, so you copy nothing else.

The client verifies a session by one of two paths. Choose by what the route needs: local verification where it needs the user's id alone, and the verification route where it needs the user's addresses, sign-in methods, or standing.

  • Local verification. Construct the client with the realm and its public keys, from the setting TURNZERO_CLOUD_REALM_KEYS. Every deploy, promote, and platform redeploy injects that setting where the environment has a realm. The client verifies the token in the process and fetches a key it does not have from GET /accounts/v0/realms/<realm>/keys. It reads the router's header x-turnzero-cloud-session on the request for the revocation verdict. A session it admits locally gives a user with empty addresses and routes, because the token carries neither. Verifying an end user shows a second client, built without keys, that reads the verified email.
  • The verification route. Construct the client without keys. It sends the session to POST /accounts/v0/verify under the application's credential TURNZERO_CLOUD_TOKEN, and needs no key set. In a local run of an application with one environment, the route accepts the development credential for production's realm. It checks a session a tester already has, and opens none.

A user who signed in only with a work account has, on the verification route, the address the company's tenant asserts, with source: "tenant". It is verified: true only where the tenant's token carries xms_edov as true and no other account already holds the address verified, and verified: false otherwise. Read verified before relying on the address. Local verification still gives no address.

The realm's keys rotate without any action from you, and revoke_realm_keys revokes every key of one environment's realm after a suspected compromise. A development realm contains at most ten end-user accounts, and a sign-in that would create another is refused development_realm_full. Verifying an end user explains the token's payload, the header's two forms, and the key rotation in full.