# Know who is signed in

Your app can greet a visitor by name and show them only their own data without building a login screen. When someone opens a restricted web app or function, Tokay signs them in and tells your code who they are on every request.

## Your code reads the visitor from the request

Tokay adds headers to each request that reaches a Restricted Service. Read them the same way you read any other header.

| Header | What it holds |
|---|---|
| `X-Tokay-Actor-Type` | `USER`, `VISITOR`, or `MACHINE` |
| `X-Tokay-Actor-Id` | A stable identifier for that person or program |
| `X-Tokay-Actor-Email` | The email address, for people |
| `X-Tokay-Actor-Name` | A display name, when we have one |
| `X-Tokay-Access-Source` | The rule or credential that admitted them |
| `X-Tokay-Session-Id` | The browser session, for people signed in through a browser |

A `USER` is someone with a Tokay account on this Workspace. A `VISITOR` is someone who only uses the app.

`X-Tokay-Actor-Id` is the value to store next to your own records. An email address can change, and the identifier stays the same.

`X-Tokay-Access-Source` is one of `OWNER`, `PROJECT_MEMBER`, `WORKSPACE_MEMBER`, `EMAIL_DOMAIN`, `ADDED`, or `MACHINE_CREDENTIAL`. See [Who can open your app](who-can-open-your-app.md) for how each source is configured.

## The headers are safe to trust

We remove any `X-Tokay-` header a caller sends before we decide anything, then add our own only after the request passes access checks. A request that reaches your code with these headers has already been checked.

Your app never sees the session cookie, credential, or token behind them.

## Anonymous requests carry no identity

A Public Service and a public path accept anyone, so those requests arrive with no identity headers at all. Treat a missing `X-Tokay-Actor-Type` as an anonymous visitor rather than an error.

A restricted dashboard and a public webhook path can share one Service. The dashboard reads the visitor, and the webhook handles requests that have no visitor.

## Browser code can ask who is signed in

A single page app often needs the visitor in JavaScript, where request headers are out of reach. Rather than adding a backend route that echoes them, fetch `/.tokay/access/me` from your own pages.

```json
{
  "authenticated": true,
  "actor": { "type": "VISITOR", "id": "...", "email": "you@example.com", "name": "Alex" },
  "accessSource": "ADDED"
}
```

When nobody is signed in, the answer is `200` with `{"authenticated": false}`. That is a normal result rather than an error, so your code reads one field instead of branching on a status code. A `503` means we could not check the session just then, which is different from a visitor being signed out. Public Services always answer `authenticated: false`, since anyone can open them and there is no session to report.

The values match the headers exactly, so server code and browser code describe the same visitor the same way.

## Programs arrive the same way

A script or CI job using a [Machine credential](machine-tokens.md) shows up as `MACHINE` with the source `MACHINE_CREDENTIAL`. The identifier stays the same when you rotate the credential, so your app's records stay valid.

A connected client acting for an admitted person adds two more headers, `X-Tokay-OAuth-Grant-Id` and `X-Tokay-OAuth-Client-Id`, which identify the approved connection and the client. The [agent access guide](agent-access.md) covers that protocol.

## Sign out belongs to Tokay

Link to `/.tokay/access/sign-out` from your app. We show a confirmation page and handle the rest, then return the visitor to the page they came from.

The page offers two choices. Signing out ends the session for every Restricted Service in the Project, matching the way one sign in covers them all. Apps in other Projects on that device stay signed in until the visitor chooses to sign out of all apps.

Add `?return_to=/some/path` when you want the visitor to land somewhere specific.

Paths beginning with `/.tokay/` belong to Tokay, so your own routes are never shadowed by ours.
