# Identity in your app

Source: https://docs.myhub.host/access/identity

Hub signs visitors in before they reach a `private` or `org` app. Your server can read these headers when needed:

| Header        | Value                                            |
| ------------- | ------------------------------------------------ |
| `X-Hub-Email` | Email                                            |
| `X-Hub-Name`  | Name; non-ASCII values are percent-encoded       |
| `X-Hub-Role`  | `owner`, `admin`, `member`, `viewer`, or `guest` |

Hub replaces visitor-supplied identity headers. Trust them only when your app is served through Hub.

```js
const roles = new Set(['owner', 'admin', 'member', 'viewer', 'guest']);

app.get('/me', (req, res) => {
  try {
    const email = decodeURIComponent(req.get('X-Hub-Email') ?? '');
    const name = decodeURIComponent(req.get('X-Hub-Name') ?? '');
    const role = req.get('X-Hub-Role');
    if (!email.trim() || !roles.has(role)) return res.sendStatus(401);
    return res.json({ email, name, role });
  } catch {
    return res.sendStatus(401);
  }
});
```

## Roles in your app

Hub controls who can open the app. Your server decides what they can do inside it.

Check the role in handlers that need authorization. Reject missing or unknown identity; never default it to `member`. Decide explicitly what guests and viewers may do. Hiding controls in the browser does not enforce permissions.

## Protect your app's writes

Hub apps share the `myhub.host` site, so `SameSite` cookies alone do not prevent requests from another app. Protect browser writes with a CSRF token or an origin check, for example:

```js
const ORIGIN = 'https://crm.acme.myhub.host';

function fromOwnPage(req) {
  const site = req.headers['sec-fetch-site'];
  const origin = req.headers.origin;
  if (site !== undefined && site !== 'same-origin') return false;
  if (origin !== undefined && origin !== ORIGIN) return false;
  return site !== undefined || origin !== undefined;
}
```

Call this check before handling a browser write. Authenticate scripted requests separately; do not accept missing headers as authorization.

For your own session cookies, use the `__Host-` prefix with `Secure`, `Path=/`, and no `Domain`, so another app cannot set them for your hostname.

## Public apps

Public apps receive no Hub identity headers. Use `private` or `org` access when your server needs these headers.