Session Management
Relevant source files
The following files were used as context for generating this wiki page:
Session management in Hodor provides a stateless, secure way to gate access to upstream applications using a single shared password. It avoids external databases by using HMAC-SHA256 signed tokens stored in browser cookies. Sources: AGENTS.md:14, README.md:10-12
The system validates every request against defined security criteria, including session tokens, public path bypasses, or network-based CIDR rules. If a request lack valid credentials, Hodor intercepts the flow and renders a login page. Sources: src/proxy.rs:72-84, AGENTS.md:16-18
Session Architecture and Token Format
Hodor uses a signed token format that combines a Unix timestamp with a cryptographic signature. This allows the server to verify the integrity and expiration of a session without storing state. Sources: src/auth/session.rs:55-56
Token Structure
A session token consists of two parts separated by a pipe (|) character:
- Unix Expiry: The expiration time in seconds since the Unix epoch.
- HMAC-SHA256 Signature: A hex-encoded signature of the expiry string, signed with the server's
SECRET.
Sources: src/auth/session.rs:55-62, AGENTS.md:21
The following diagram illustrates the token generation and validation flow:
Sources: src/auth.rs:88-101, src/auth/session.rs:57-62
Authentication Flow
Hodor evaluates authentication using a specific hierarchy during the request lifecycle. The proxy_or_login handler determines if a request should be forwarded to the upstream or redirected to the login gate. Sources: src/proxy.rs:60-70
Resolution Logic
- Public Paths: Matches the request path against
BYPASS_PATHS. - Session Cookies: Validates the
hodorcookie using the configuredSECRET. - Network Bypass: Checks if the client IP falls within
BYPASS_CIDRS.
Sources: src/proxy.rs:72-84, AGENTS.md:16-18
Forwarded Authentication Headers
Once authenticated, Hodor strips any client-supplied X-Hodor-* headers to prevent forgery. It then injects its own X-Hodor-Auth header to inform the upstream service how the request was cleared. Sources: src/proxy.rs:163-176, README.md:144-150
| Header Value | Description |
|---|---|
password | Client presented a valid signed session cookie. |
bypass | Client IP matched a network CIDR in BYPASS_CIDRS. |
public | Request path matched a pattern in BYPASS_PATHS. |
Sources: src/proxy.rs:25-30, README.md:148
Session Lifecycle Management
Session Creation
Upon a successful constant-time password comparison, the server generates a token. It issues a Set-Cookie header with the following attributes:
- HttpOnly: Prevents client-side scripts from accessing the cookie.
- SameSite=Lax: Protects against Cross-Site Request Forgery (CSRF).
- Max-Age: Derived from the
SESSION_TTLconfiguration. - Secure: Included only if
SECURE_COOKIEis enabled.
Sources: src/auth/session.rs:40-52, src/auth.rs:94-101
Session Termination
The /_gate/logout endpoint clears the session. It issues a cookie with Max-Age=0, effectively instructing the browser to delete the token immediately. Sources: src/auth/session.rs:48-52, src/auth.rs:52-61
Cryptographic Secret Management
The SECRET key signs all session tokens. If no secret is provided in the configuration, Hodor generates an ephemeral 32-byte random key at startup. Using an ephemeral key means all sessions become invalid if the process restarts. Sources: src/auth/session.rs:89-98, src/state.rs:71
Sources: src/auth.rs:64-105, src/proxy.rs:88-154
Configuration Options
Session behavior is controlled via several environment variables and configuration keys. Sources: src/config.rs:10-40
| Option | Env Var | Default | Description |
|---|---|---|---|
session_ttl | SESSION_TTL | 86400 (24h) | Duration in seconds before a session expires. |
secret | SECRET | Random | Key used for HMAC signing. Persistent value ensures sessions survive restarts. |
secure_cookie | SECURE_COOKIE | false | Enables the Secure flag (requires HTTPS). |
cookie_domain | COOKIE_DOMAIN | None | Optional domain scope for the session cookie. |
Sources: src/config.rs:24-40, README.md:75-100
Implementation Details
Constant-Time Validation
To prevent timing attacks, Hodor compares the provided password against the configured password using constant-time operations. Sources: src/auth.rs:81-83, AGENTS.md:17
// src/auth.rs:81-83
if !bool::from(password.as_bytes().ct_eq(state.password.as_slice())) {
// failure logic
}
Signature Verification
The verification process decodes the hex signature, parses the expiry, and re-calculates the HMAC to ensure it matches the provided signature. It explicitly checks if the current time is past the expiry timestamp. Sources: src/auth/session.rs:66-86
Session management concludes Hodor's security model by ensuring that only requests with valid, unexpired, and untampered signatures—or those meeting specific network and path exceptions—reach the upstream application.