Sessions and user state
The Session Management system provides enterprise-grade session security for mission-critical applications. Maverics sessions are comprehensive containers that hold the complete user context needed for identity orchestration.
A Maverics session
encompasses the user’s authentication state, attributes
retrieved from multiple identity sources (like Active Directory, databases, or APIs),
and any metadata associated with the user’s journey through your applications. Think
of it as a secure, ephemeral server-side profile that aggregates everything needed to
make intelligent access decisions across your entire infrastructure.
This comprehensive approach enables identity orchestration across hybrid and cloud environments. Organizations can extend cloud identity services like Azure AD to protect legacy on-premises applications, gradually migrate users from outdated identity systems to modern platforms, and create seamless single sign-on experiences that span completely different technologies. Sessions bridge the gap between disparate identity systems while maintaining both security and user experience.
Security Features
Cryptographically Secure Session Identifiers
Session identifiers are generated using a cryptographically secure random number generator (CSPRNG) with 256-bit entropy. This provides:
- 2256 possible session IDs - making brute force attacks computationally infeasible
- Exceeds OWASP recommendations - OWASP requires minimum 64-bit entropy; Maverics has 256-bit entropy
- Zero predictability - each session ID is completely independent and unpredictable
Session Cookie Security
By default, all session cookies are configured with maximum security settings:
- Session Cookies Only - Cookies are automatically deleted when the browser closes (MaxAge = 0)
- HTTPS Only (Secure flag) - Cookies are only transmitted over encrypted connections
- HttpOnly Protection - Prevents client-side JavaScript access to session cookies
- SameSite=None - Enables secure cross-site authentication flows while maintaining protection
These settings help protect against:
- Session hijacking via network interception
- Cross-site scripting (XSS) attacks
- Cross-site request forgery (CSRF) attacks
- Session fixation attacks
Default Session Lifetime
Sessions are configured with secure default timeouts:
- Maximum Session Lifetime: 24 hours
- Idle Timeout: Disabled by default (can be configured)
- Automatic Cleanup: Expired sessions are automatically purged from the backing storage service
This balances security with user experience, ensuring sessions don’t persist indefinitely while minimizing authentication friction for legitimate users.
Session Termination
The Orchestrator can explicitly terminate user sessions to ensure immediate security enforcement and compliance requirements.
Immediate Effects
- All session data is deleted - User attributes, authentication state, and metadata are removed from the session store
- Session cookie is invalidated - The user’s browser receives an expired cookie that will be automatically discarded
- User access is revoked - Any subsequent requests using the terminated session will be denied and end-users will send users back through the authentication and authorizations flows.
Common Termination Scenarios
Session termination occurs automatically in several situations:
- User logout - When users explicitly sign out through your application
- Timeout expiration - Sessions that exceed maximum lifetime or idle timeout limits
Security Benefits
Explicit session termination provides immediate security enforcement:
- Rapid response to security incidents - Compromised accounts can be immediately secured
- Compliance requirements - Meet regulatory standards requiring immediate access revocation
- Zero-trust enforcement - Ensure users must re-authenticate after privilege changes
- Clean session state - Prevents stale authentication data from affecting future access decisions
Session Cookie
The Orchestrator uses a non-persistent session cookie to maintain an end-user’s state. The lifetime of the cookie is determined by the configured maximum lifetime and idle timeout values.
The session cookie is an opaque cookie that contains only a session identifier. The session identifier is generated using a cryptographically secure random number generator with 256-bit entropy. All other session state is maintained on the Orchestrator server rather than being stored in the cookie itself.
Key characteristics of the Maverics session cookie:
- Opaque identifier only - No sensitive data stored in the cookie
- Server-side state management - All user attributes and session data stored securely on the server
- Cryptographically secure generation - 256-bit entropy ensures unpredictable session identifiers
- Configurable cookie attributes - Security settings can be customized while maintaining best practices
Configuration options
session
declares the set of configuration options for session management.
Cookie
cookie
is an optional field used to define settings for the HTTP cookie that is
used to tie a user back to their session.
Domain
domain
is an optional field that specifies the hosts to which the session cookie
will be sent. This should normally be set only when proxying to multiple apps on the
same domain. If not set, the cookie domain attribute
will be set to the hostname requested by the client.
For example, if domain
is set to example.com
, the user agent will include the
cookie in the Cookie
header when making HTTP requests to example.com
and all
subdomains of *.example.com
.
Name
name
is an optional field that specifies the name of the session cookie used by the
Maverics Orchestrator. The default session cookie name is maverics_session
.
Disable HTTP Only
disableHTTPOnly
is an optional field that disables the
HttpOnly
cookie attribute. Defaults to
false. If set to true, the session cookie will not have the HttpOnly
attribute,
allowing the cookie to be accessed via client side scripts.
Disable Secure
disableSecure
is an optional field that disables the
Secure
cookie attribute.
Defaults to false. If set to true, the session cookie will not have the Secure
attribute, allowing the browser to send the cookie over an unencrypted HTTP request.
Lifetime
lifetime
is an optional field that defines the session lifetime.
Max Timeout
maxTimeout
is an optional field that represents the maximum amount of time
that can elapse post-authentication before a session’s authentication state becomes
invalidated. If no value is specified, a default of 24 hours will be used.
Idle Timeout
idleTimeout
is an optional field that represents the amount of time a session may
remain idle before timing out. If no value is set, or the idle timeout is set to 0, then
the session idle timeout is disabled.
Eval Session Max Lifetime
evalMaxLifetimeSE
is an optional field to define a Service Extension that
determines how sessions reaching their max lifetime are handled. maxLifetimeSeconds
is still used for individually expiring attributes.
Eval Session Idle Timeout
evalIdleTimeoutSE
is an optional field to define a Service Extension that
determines how session idle timeouts are handled. If this Service Extension is
defined, then the idleTimeout
value is ignored.
Store
store
is an optional field that defines the session storage backend.
Type
Specifies the session storage backend. Currently, the only available store is "local"
.
Other stores will be added in the future.
Local
local
defines the configuration for the local session store type.
Capacity
capacity
is an optional field that limits the number of sessions maintained in
memory. When the session cache has reached its maximum capacity, and a new session is
requested, the session management removes the least recently used session from the
cache to make room for the new one. If capacity
is not set, a default value of
50,000 user sessions will be used.
Examples
Base Configuration
This configuration will trigger a session expiration after the user is idle for 30 minutes and after a maximum period of one hour. On session expiration, the user will be required to reauthenticate with the IDPs associated with the defined policy.
session:
cookie:
domain: example.com
disableHTTPOnly: false
disableSecure: false
lifetime:
maxTimeout: 1hs
idleTimeout: 30m
Session Expiration via Service Extension
Service extensions allow complete flexibility over the process of controlling a user’s session lifespan. The example below triggers single logout on a session expiry event. The max session timeout and idle session timeout are determined dynamically depending on the user’s employee type (full-time employee vs contractor).
/etc/maverics/maverics.yaml
session:
cookie:
domain: example.com
lifetime:
evalMaxLifetimeSE:
funcName: EvalMaxLifetime
file: /etc/maverics/extensions/session.go
evalIdleTimeoutSE:
funcName: EvalIdleTimeout
file: /etc/maverics/extensions/session.go
singleLogout:
logoutURL: https://example.com/single-logout
postLogout:
redirectURL: https://example.com/index.html
/etc/maverics/extensions/session.go
package main
import (
"net/http"
"time"
"github.com/strata-io/service-extension/orchestrator"
)
const (
sloEndpoint = "https://example.com/single-logout"
contractorIdleTimeoutSeconds = 300
contractorMaxTimeoutSeconds = 3600
fteIdleTimeoutSeconds = 3600
fteMaxTimeoutSeconds = 43200
)
// EvalMaxLifetime determines whether a session has reached its max lifetime. The
// expiration check is informed by a whether a user is a full-time employee or
// contractor.
func EvalMaxLifetime(
api orchestrator.Orchestrator,
rw http.ResponseWriter,
req *http.Request,
createdAt time.Time,
) bool {
logger := api.Logger()
sess, err := api.Session()
if err != nil {
logger.Error(
"se", "failed to retrieve session",
"err", err,
)
return false
}
employeeType, err := sess.GetString("okta.employeeType")
if err != nil {
logger.Error(
"se", "failed to retrieve 'employeeType'",
"err", err,
)
return false
}
maxTimeout := contractorMaxTimeoutSeconds
if employeeType == "full_time" {
maxTimeout = fteMaxTimeoutSeconds
}
if sessionExpired(createdAt, maxTimeout) {
logger.Info(
"se", "user has reached max session lifetime: redirecting to SLO endpoint")
http.Redirect(rw, req, sloEndpoint, http.StatusFound)
// False is returned here so that the SLO endpoint is aware which IDPs to log
// the user out of. If true is returned, all session attributes including the
// list of authenticated IDPs will be cleared.
return false
}
return false
}
// EvalIdleTimeout determines whether a session has reached its idle timeout. The
// expiration check is informed by a whether a user is a full-time employee or
// contractor.
func EvalIdleTimeout(
api orchestrator.Orchestrator,
rw http.ResponseWriter,
req *http.Request,
lastAccess time.Time,
) bool {
logger := api.Logger()
sess, err := api.Session()
if err != nil {
logger.Error(
"se", "failed to retrieve session",
"err", err,
)
return false
}
employeeType, err := sess.GetString("okta.employeeType")
if err != nil {
logger.Error(
"se", "failed to retrieve 'employeeType'",
"err", err,
)
return false
}
idleTimeout := contractorIdleTimeoutSeconds
if employeeType == "full_time" {
idleTimeout = fteIdleTimeoutSeconds
}
if sessionExpired(lastAccess, idleTimeout) {
logger.Info("se", "user has reached idle session lifetime: redirecting to SLO endpoint")
http.Redirect(rw, req, sloEndpoint, http.StatusFound)
// False is returned here so that the SLO endpoint is aware which IDPs to log
// the user out of. If true is returned, all session attributes including the
// list of authenticated IDPs will be cleared.
return false
}
return false
}
func sessionExpired(startPoint time.Time, timeout int) bool {
return startPoint.Before(time.Now().Add(-time.Duration(timeout) * time.Second))
}