> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dubot.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Identity and context

> Identify the end user without exposing the workspace verification secret

Dubot uses three different values at the browser boundary.

| Value          | Purpose                                                  | Secret?                                              |
| -------------- | -------------------------------------------------------- | ---------------------------------------------------- |
| Client token   | Selects the workspace and SDK rollout                    | No                                                   |
| User id        | Stable customer-owned identifier for the signed-in user  | No                                                   |
| Identity token | Proves that the customer server vouches for that user id | Yes, until delivered to the intended browser session |

## Mint the identity token on your server

Use the workspace identity-verification secret to sign an HS256 JWT. The subject must equal the
`userId` passed to `Dubot.init()`, and expiration must be no more than seven days in the
future. Shorter lifetimes are recommended.

```js theme={null}
import jwt from 'jsonwebtoken';

const identityToken = jwt.sign(
  {
    sub: currentUser.id,
    exp: Math.floor(Date.now() / 1000) + 60 * 60,
  },
  process.env.DUBOT_IDENTITY_VERIFICATION_SECRET,
  { algorithm: 'HS256' },
);
```

Return that token through your authenticated application response, then initialize Dubot in the
browser:

```js theme={null}
await window.Dubot.init({
  userId: currentUser.id,
  email: currentUser.email,
  identityToken,
});
```

<Warning>
  Never expose `DUBOT_IDENTITY_VERIFICATION_SECRET` to the browser. Rotating the secret makes
  previously minted tokens fail verification immediately.
</Warning>

## Observe before enforcing

Workspace settings can observe or enforce signed identities separately for Test and Production.

* **Observe** records whether identified sessions present a valid signature without blocking
  unsigned traffic.
* **Enforce** rejects missing, invalid, expired, or mismatched identity tokens.

Use the recent coverage summary before changing an environment from Observe to Enforce.

`getState().initProps.verified` means the browser supplied a non-empty identity token. It does not
prove the server accepted that token. Verify acceptance with a successful authenticated request
and the workspace identity coverage view.

## Recover from an enforcement failure

If Enforce blocks intended users, return the affected environment to Observe while you repair the
integration. Confirm the user id and JWT subject match, mint a fresh token with the current secret,
and watch coverage before enabling Enforce again. Rotating the secret is appropriate only when you
intend to invalidate every outstanding token.

## Supply session context

`context` is a flat map of scalar values. The current SDK bounds it to approximately 2 KB and
drops nested values or overflow with a console warning.

```js theme={null}
window.Dubot.setContext({
  plan: 'pro',
  invoice_open: true,
  open_invoice_id: 'inv_1042',
});
```

`setContext()` replaces the complete context set. Rebuild and send the full current snapshot
when the host state changes.

For a single-page application, update the snapshot after route or relevant account state changes;
do not call `init()` again only to refresh context.

```js theme={null}
function syncDubotContext() {
  window.Dubot.setContext({
    route: window.location.pathname,
    plan: currentAccount.plan,
    invoice_open: Boolean(currentInvoice),
  });
}

router.onRouteChange(syncDubotContext);
accountStore.onChange(syncDubotContext);
```

The subscription APIs above are placeholders for the equivalent hooks in your application. The
important contract is to send one complete, flat snapshot whenever relevant host state changes.

<Note>
  Email is used for identity attribution when passed to `init()`. It is not automatically copied
  into assistant context. Add only the context fields the experience actually needs.
</Note>

See [Troubleshoot the browser SDK](/sdk/troubleshooting#identity-requests-fail) for the failure
checklist.

## Renew an identity token

Your application obtains fresh tokens from its authenticated backend; the SDK does not mint or
schedule their renewal. Before the token expires, call `init()` with the same user's full options
and the new token:

```js theme={null}
await window.Dubot.init({
  ...currentDubotOptions,
  identityToken: freshIdentityTokenFromYourBackend,
});
```

`currentDubotOptions` is the complete initialization configuration maintained by your application.
When only the token changes, the SDK refreshes it without remounting placements and reconnects
the action channel as needed. A changed user or other initialization options can restart the
configuration lifecycle. Use `setContext()` or `setActions()` for their respective updates.

## Log out or switch accounts

End the old user's Dubot session as part of logout or account switching:

```js theme={null}
window.Dubot.destroy();
```

Then perform a full page navigation through your application's logout or account-switch flow.
On the next page, load the SDK and initialize it only after the new identity and token are ready.
This tears down active surfaces and action-channel presence; changing context alone does not
change the authenticated user.

`destroy()` is terminal for the installed instance. Calling `init()` afterward is ignored, and
inserting the CDN script again in the same document is treated as a duplicate install. Use a
full page reload when you need a fresh instance. For an application that must switch users
without navigation, review its reinitialization and conversation-isolation behavior with Dubot
before rollout.
