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

# Chat identity verification

> Sign chat widget variables so they pass the Trusted-only check on actions and lookups

Chat widget variables come from the browser, so a visitor can change them.
That works for preferences like locale or theme, but not for identity, where
a spoofed value would let anyone impersonate another customer.

Identity verification adds a JWT your backend signs with a Typewise secret.
The chat SDK sends the token alongside the widget, Typewise verifies the
signature, and the claims inside become the trusted set.

## When you need it

Turn on identity verification if any chat action or lookup uses the
**Trusted only** check on an input mapped to a context variable. See
[Context Variables](/documentation/settings/context-variables). Without a
valid signature, the variable's value isn't verified, the check fails, and
the conversation either asks the customer to confirm (for `user_email`) or
hands off to a Human Agent.

For variables that don't need to be trusted (UI locale, display theme,
feature flags), you can skip this.

## Get your signing secret

<Steps>
  <Step title="Open Identity verification">
    Go to [Identity
    verification](https://platform.typewise.app/channels/chat/installation/identity-verification)
    under chat installation.
  </Step>

  <Step title="Copy the key">
    Copy the `sk_...` value shown in the panel and store it in your backend's
    secrets manager. You can regenerate it any time, which invalidates the
    previous key.
  </Step>
</Steps>

## Sign the token on your backend

<Warning>
  Never expose the signing key to the browser or commit it to source control.
  Anyone who holds it can forge any variable for any customer. Keep it
  server-side only.
</Warning>

Sign a JWT with HS256 using the secret. Put the variables you want
trusted in the payload. Keep expiry short (7 days or less).

<CodeGroup>
  ```javascript Node.js theme={null}
  import jwt from 'jsonwebtoken';

  const token = jwt.sign(
    {
      user_email: 'john.doe@example.com',
      subscription_tier: 'premium',
    },
    process.env.TYPEWISE_SDK_SECRET,
    { expiresIn: '7d' },
  );
  ```

  ```python Python theme={null}
  import jwt, os
  from datetime import datetime, timedelta

  token = jwt.encode(
      {
          'user_email': 'john.doe@example.com',
          'subscription_tier': 'premium',
          'exp': datetime.utcnow() + timedelta(days=7),
      },
      os.environ['TYPEWISE_SDK_SECRET'],
      algorithm='HS256',
  )
  ```

  ```php PHP theme={null}
  use Firebase\JWT\JWT;

  $token = JWT::encode(
    [
      'user_email' => 'john.doe@example.com',
      'subscription_tier' => 'premium',
      'exp' => time() + 60 * 60 * 24 * 7,
    ],
    $_ENV['TYPEWISE_SDK_SECRET'],
    'HS256',
  );
  ```
</CodeGroup>

Return the token only to the authenticated page. The signing secret stays on
your server.

## Pass the token to the widget

```javascript theme={null}
window.twConfig = {
  clientId: "YOUR_CLIENT_ID",
  signedVariables: "<JWT from your backend>",
  variables: {
    locale: "en-US",
  },
};
```

Values in `signedVariables` are verified. Values in `variables` stay
unsigned and fail the **Trusted only** check on any input mapped to them.

## Verification outcomes

| Signature                    | Variables treated as | Pass the Trusted-only check |
| :--------------------------- | :------------------- | :-------------------------- |
| Valid JWT                    | Verified             | Yes                         |
| Invalid, missing, or expired | Unverified           | No                          |

Invalid signatures don't reject the session. The variables are simply marked
unverified. If an action then hits a **Trusted only** input mapped to one of
them, the runtime rules in
[Context Variables](/documentation/settings/context-variables#when-a-trusted-only-input-is-not-satisfied)
apply.

## See also

* [Context Variables](/documentation/settings/context-variables): declare
  context variables and customize action and lookup inputs
* [Security & verification](/documentation/actions/security): the trust model
  behind input customization
* [Chat configuration](/documentation/behavior/chat): chat channel overview
