# Login plugin storage keys

The pre-integrated login plugins persist authentication data in local storage. This lets the app restore a logged-in session after an app restart and gives other integrations access to authentication values through Context Keys.

This page documents the default namespaces and keys written by the three main login plugins:

- [Login Flow](./implementing-login-flow.md), used for custom login APIs and Roku.
- [TV OAuth 2.0](../../using-zapp/auth/tv-login.md), used for device and PIN-based TV login.
- [OAuth 2.0](./oauth2-integration-guide.md), used for OAuth 2.0 and OIDC login flows.

## Default plugin storage

Unless a response includes additional `extensions.storage_keys`, the plugins use the following local-storage namespaces and keys.

| Plugin | Namespace | Default keys |
| --- | --- | --- |
| Login Flow | `quick-brick-login-flow` | `token`, `access_token`, `refreshToken`, `refresh_token`, `data`, `id_token`, `refresh_url`, `username`, `name`, `last_name`, `rivers_configuration_id`, and `refresh_date_unix_timestamp` |
| TV OAuth 2.0 | `quick-brick-login-flow` | `access_token`, `id_token`, `refresh_token`, `expires_in`, `deviceId`, `end_point_data`, `auth_provider`, and `refresh_date_unix_timestamp` |
| OAuth 2.0 | `quick-brick-login-flow` | `authData`, `access_token`, `idToken`, `id_token`, and any extracted token or ID-token claims |

The exact set of keys can grow when the login response contains additional storage data. The Login Flow and TV OAuth 2.0 plugins merge `response.extensions.storage_keys` into their storage values. OAuth 2.0 does the same for `tokenAdditionalParameters.extensions.storage_keys` or `additionalParameters.extensions.storage_keys`.

### Extracting JWT claims

The OAuth 2.0 plugin can decode JWT claims and write them to local storage when the corresponding configuration flags are enabled:

- **Extract Token Claims to Storage**: decodes the access token and merges its claims into the `quick-brick-login-flow` namespace.
- **Extract ID Token Claims to Storage**: decodes the ID token and stores its claims in the `quick-brick-login-flow-id_token` namespace.

These flags are useful when downstream requests need values such as a subject, email, entitlement, or tenant claim as Context Keys. They only apply when the token is a decodable JWT. If a provider returns an opaque token or a non-JWT value, the plugin keeps the normal token data and skips claim extraction.

### Local storage and session storage

Authentication data and tokens are written to **local storage**. The Login Flow plugin's `rivers_configuration_id` is read from session storage, but the login response data is stored locally.

The OAuth 2.0 plugin reads its plugin configuration from session storage under the plugin namespace `zapp_login_plugin_oauth_2_0`. This configuration namespace is separate from the local-storage namespace used for login data. Do not use the configuration namespace as the token storage namespace.

## The `user_account` namespace

`user_account` is a reserved scope for user-specific persistent context data. It is not the default namespace for the tokens listed above.

Use `user_account` when data should follow the authenticated user and be removed automatically at logout. For Runtime URL context, provide the scope and values as `persistent_keys`:

```json
{
  "persistent_keys": {
    "scope": "user_account",
    "content": {
      "profile": {
        "user_id": "12345",
        "plan": "premium"
      }
    }
  }
}
```

The application clears every key in the `user_account` namespace on logout in both local storage and session storage. This behavior is implemented by the action executor's logout subscriber and is also described in [Set Context](../set-context.md#scoped-persistent-keys).

Because the namespace is cleared wholesale, do not put device-wide or application-wide data in `user_account`. Store only values that are safe to discard when the current user logs out.

## Choosing a key

When configuring a downstream integration that needs a token or user identifier:

1. Use the namespace and key written by the login plugin in use, for example `quick-brick-login-flow.access_token`.
2. If the integration needs user-specific profile data rather than a token, write that data as scoped persistent context with `scope: "user_account"`.
3. Do not assume that a key is available in both local and session storage. Check the plugin's storage contract and the platform-specific login guide.

Tokens are sensitive values. Expose only the minimum required value to downstream requests, and avoid copying access or refresh tokens into additional namespaces unless the integration requires it.
