Session duration (admin)
A dashboard session expires after a fixed window. This page covers how an org owner adjusts that window for their tenant: where the value lives, who can change it, and how the deviation is recorded.
The member-facing surface (members viewing and revoking their own sessions) lives in Sign-in & access control → Session management.
The two places duration is set
Section titled “The two places duration is set”Upwarden resolves session_duration_minutes per sign-in in two layers:
- Platform default. The operator (you, if you run the install) sets
STYTCH_SESSION_DURATION_MINUTESin the engine environment. Default: 60 minutes. This is the value every tenant gets when no override is set. - Per-tenant override. An Org-tier or Enterprise-tier owner can override the platform default for their own tenant via the policy-override surface. The override wins for that tenant only; other tenants on the same install keep the platform default.
The resolver lives in src/auth/stytch-login.ts:resolveEffectiveSessionDurationByStytchOrg. It reads the override at sign-in time (no cache) so an owner who just tightened the duration sees the new value on their very next sign-in.
Who can override
Section titled “Who can override”Owner role on a tenant on Org or Enterprise tier. Free and Team tenants are stuck with the platform default; the upgrade path is “go to Org to unlock policy overrides”.
This is the same tier + role gating as every other policy override — see Policy overrides for the full mechanics.
Bounds
Section titled “Bounds”The override accepts a whole number of minutes within:
- Floor: 5 minutes. Below Stytch’s documented per-session minimum — the SDK would reject anything shorter; Upwarden 400s at the API instead of bubbling a 502 from Stytch.
- Ceiling: 1440 minutes (24h). Safety bound that sits below the project-level
sessions.max_session_duration_minutescap on the Stytch project. Operators who need longer sessions raise both the constant insrc/policy/session-duration-override.tsxand the Stytch project ceiling together.
Anything outside the bounds 400s with a customer-facing reason string (e.g. session_duration_minutes must be at least 5 minutes).
Tighten vs. loosen
Section titled “Tighten vs. loosen”Per the Policy override model:
- Shorter than the platform default = tighter. The override saves with no typed acknowledgement. Example: dropping from 60 to 30.
- Longer than the platform default = looser. The override demands a typed
acknowledgement_textbefore the save button enables. The text lands in the audit row so an auditor can verify the operator put their name on the deviation. Example: extending from 60 to 240.
Setting it
Section titled “Setting it”From the dashboard
Section titled “From the dashboard”/admin/ui/orgs/<slug>/settings/policies — pick the Session duration (minutes) row, click Edit, enter the new value. If the new value is longer than the platform default, fill in the acknowledgement field.
From the JSON admin API
Section titled “From the JSON admin API”# Tightening (60 → 30): no acknowledgement required.curl -fsS -X PUT \ -H "x-upwarden-admin-token: $ADMIN_API_TOKEN" \ -H "content-type: application/json" \ -d '{ "value": 30 }' \ "https://vg-admin.<your-domain>/api/v1/admin/orgs/<slug>/policy-overrides/session_duration_minutes"
# Loosening (60 → 240): acknowledgement_text required.curl -fsS -X PUT \ -H "x-upwarden-admin-token: $ADMIN_API_TOKEN" \ -H "content-type: application/json" \ -d '{ "value": 240, "acknowledgement_text": "Approved by CISO — 4h dashboard sessions for incident-response operators only" }' \ "https://vg-admin.<your-domain>/api/v1/admin/orgs/<slug>/policy-overrides/session_duration_minutes"Removing the override
Section titled “Removing the override”DELETE the override to fall back to the platform default:
curl -fsS -X DELETE \ -H "x-upwarden-admin-token: $ADMIN_API_TOKEN" \ "https://vg-admin.<your-domain>/api/v1/admin/orgs/<slug>/policy-overrides/session_duration_minutes"(Or Reset to default on the dashboard.) The audit row carries event_string = policy_override_restored with policy_name = session_duration_minutes. From the next sign-in onwards the platform default applies again.
How members experience a change
Section titled “How members experience a change”Session duration is resolved at sign-in time, not on every request. A change to the override takes effect on the next sign-in for each member:
- Currently signed-in members keep the session they already have at the old duration. Their session expires whenever it was originally set to expire.
- The next sign-in (theirs, or a new member’s) picks up the new duration. Magic-link logins, OAuth, passkey, SSO, and TOTP completions all read through the same resolver.
If an owner needs the new duration applied to everyone right now (e.g. tightening in response to an incident), they can force-logout the org via the super-admin surface (Enterprise) or the JSON admin API — every member’s next action is a re-authentication that picks up the new duration. See Sign-in & access control → Session management for the force-logout audit envelopes.
Audit posture
Section titled “Audit posture”Setting, changing, and clearing the override each write one row into audit_log. The envelopes follow the standard policy-override shape — see Policy overrides → Audit envelopes.
Concretely, for the session-duration policy:
| Event | Carries |
|---|---|
policy_override_tightened | { policy_name: "session_duration_minutes", default_value, override_value, by_user_id } |
policy_override_loosened | { policy_name: "session_duration_minutes", default_value, override_value, acknowledgement_text, by_user_id } |
policy_override_restored | { policy_name: "session_duration_minutes", by_user_id } |
Pivot by policy_name = session_duration_minutes to get a per-tenant history of every duration change. Pivot by by_user_id to attribute the change to a specific operator.
What’s next
Section titled “What’s next”- Policy overrides — the surface this page is a specialisation of.
- Sign-in & access control — the member-facing session-management surface.
- Querying the audit log — find the override rows.