# Protecting content

Content gating is driven by two pieces of state on the user object — **`isAuthenticated`** and **`productAccess`** — kept in sync by the **`userChange`** event.

***

## Reading access

Combine `isAuthenticated` with `productAccess` to decide what to show:

* If `isAuthenticated` is `false`, show the public experience or your sign-in / pricing UI.
* If `isAuthenticated` is `true`, check whether the relevant product ID is in `productAccess`. If yes, unlock the gated experience; if not, offer an upgrade.

The shape of the user object is documented in [User object](/reference/authentication/user-object.md). The semantics of the `productAccess` array — what it contains, when it changes — are documented in [Product access](/reference/checkout/product-access.md).

***

## Reacting to changes

Subscribe to `userChange` and update your UI from the event payload. It fires on session init, after login, after checkout, after logout, and any time entitlements change — so your gates stay aligned without polling.

| Trigger                | Method                         | Resulting `userChange` event                                                      |
| ---------------------- | ------------------------------ | --------------------------------------------------------------------------------- |
| User subscribes        | `tiun.checkout({ productId })` | `event: 'checkout'`, user authenticated, `productAccess` reflects the new product |
| Returning visitor      | Automatic on page load         | `event: 'init'`, session restored                                                 |
| Existing user signs in | `tiun.login()`                 | `event: 'login'`, user authenticated                                              |
| User signs out         | `tiun.logout()`                | `event: 'logout'`, `user` is `null`                                               |

***

## Example

```javascript
tiun.on('userChange', (data) => {
  const { isAuthenticated, user } = data;

  if (!isAuthenticated || !user) {
    showPublicExperience();
    return;
  }

  const hasPremium = user.productAccess.includes('YOUR_PRODUCT_ID');

  if (hasPremium) {
    showPremiumContent();
  } else {
    showUpgradePrompt();
  }
});
```

For all event names and full payloads, see [SDK events](/sdk/reference/events.md).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.tiun.io/reference/authentication/protecting-content.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
