When a user signs in, Authdog issues a signed JWT. Your app checks that token on later requests. Session security is how long that token stays valid, how many devices may hold one, and how you take it back.

The model is in [Sessions and tokens](/docs/concepts/sessions-tokens). This page is the settings.

## Lifetime

Two clocks, and they are not the same setting:

- **Token lifetime** (**Authentication > Sessions**) is how long an access token stays valid after it is issued. The range is 0–100,000 seconds. The default is 3,600 seconds (1 hour). Shorten it when a leaked token must die quickly. Lengthen it only for clients that cannot refresh often. A lifetime of 0 is not a session. Leave a window your app can refresh inside.
- **Session timeout (minutes)** (**Users > Settings**, in Registration & sign-in) is idle invalidation. A user who walks away loses the session even if the token lifetime has not elapsed.

**Allowed clock skew** on the Sessions tab (default 60 seconds, max 600) is tolerance between your clock and Authdog's. It is not extra lifetime. Raising it to hide a bad NTP setup also accepts tokens that are already expired by that many seconds.

New values apply to tokens issued after you save. Tokens already in the wild keep the lifetime they were born with.

## How many sessions

**Allow concurrent sessions** lets one user stay signed in on more than one device. Turn it off when the product is a single active device: a new sign-in should replace the previous one.

Concurrent sessions do not weaken the signature. They widen the set of tokens you may need to revoke.

## Cookie and bearer

The same JWT arrives two ways:

- `authdog-session` on the browser: `HttpOnly`, `SameSite=Lax`, and `Secure` in production.
- `Authorization: Bearer` when the client cannot store that cookie.

Treat the bearer like a password. It is readable by whatever holds it. The cookie is not readable by page scripts. [Web security](/docs/secure/web-security) covers the difference.

## Revocation

Sign-out clears the cookie and ends that session. A stolen bearer is still a valid signature until it expires, unless something else fails the next check.

These end outstanding sessions on the next `userinfo` call:

- Suspend or delete the [user](/docs/users).
- Rotate or revoke the environment signing key. Follow [Rotate your API keys](/docs/secure/rotate-keys) so you don't reject tokens that are still legitimately in flight.
- An inactive user is refused at sign-in. The browser goes to the account-disabled page.

Your API should call `userinfo` (the SDK does this) when the decision matters. A local signature check alone cannot see a suspension that happened after the token was issued.

## Related

| Read | To learn how to |
| --- | --- |
| [Sessions and tokens](/docs/concepts/sessions-tokens) | Claims, refresh, and how validation works |
| [Sessions](/docs/console/sessions) | Token lifetime, clock skew, and signing keys |
| [Rotate your API keys](/docs/secure/rotate-keys) | Swap a signing key without downtime |
| [Backend requests](/docs/backend) | Validate the session on your server |
