webgates-sessions 1.0.0

Framework-agnostic session lifecycle and renewal primitives for webgates.
Documentation
# webgates-sessions

User-focused session lifecycle and renewal primitives for the `webgates` ecosystem.

`webgates-sessions` is the session layer of the workspace. It provides the framework-agnostic types, repository contracts, and service workflows needed to issue, renew, rotate, and revoke session-backed authentication.

This crate intentionally keeps HTTP and cookie behavior out of scope. That lets session rules live in one place while adapters such as `webgates-axum` remain responsible for request parsing, cookie extraction, and response mutation.

## Who this crate is for

Use `webgates-sessions` when you want to:

- issue short-lived auth tokens backed by longer-lived refresh-token sessions
- model refresh-token rotation and replay handling
- coordinate renewal attempts with short-lived leases
- implement framework-agnostic session issuance, renewal, and revocation
- define or implement repository contracts for persisted session state
- build custom integrations outside HTTP frameworks

If you want the higher-level application composition, use `webgates`.
If you want Axum transport integration, use `webgates-axum`.
If you want repository implementations, use `webgates-repositories`.

## What this crate provides

`webgates-sessions` is designed for applications that want:

- short-lived auth tokens
- long-lived refresh-token-backed sessions
- framework-agnostic session issuance and renewal
- replay-aware refresh-token rotation
- explicit repository contracts for persistent session storage
- deterministic in-memory-friendly semantics for tests and local development

## Install

Add the crate directly if you want the session layer by itself:

```toml
[dependencies]
webgates-sessions = "1.0.0"
```

Or use it through the user-facing `webgates` composition crate:

```toml
[dependencies]
webgates = { version = "1.0.0", default-features = false, features = ["authn", "codecs", "repositories", "secrets", "sessions"] }
```

Minimum supported Rust version: `1.91`.

## The mental model

The easiest way to understand this crate is:

1. a successful login issues an auth token plus a refresh token
2. the auth token is short-lived and used for request authorization
3. the refresh token is long-lived, opaque, and stored only as a hash on the server side
4. renewal rotates the refresh token and usually issues a fresh auth token
5. replay or logout can revoke one session or an entire session family

## Core concepts

### 1. Session-backed authentication

A successful login can issue:

- an auth token for request authorization
- an opaque refresh token for session continuity

The auth token is intended to be short-lived. The refresh token is intended to be stored only as a hash on the server side and rotated whenever renewal succeeds.

### 2. Renewal coordination

Concurrent renewal attempts are coordinated through short-lived renewal leases:

- one request acquires the lease and performs rotation
- parallel requests can detect lease contention
- near-expiry requests may continue when the current auth token is still valid
- expired-auth requests require successful renewal before proceeding

### 3. Replay handling

Refresh-token reuse after rotation is treated as a compromise signal. Session implementations built on this crate can revoke the affected session family when replay is detected.

## How the crate is organized

The crate is split by responsibility so you can learn it in layers:

- `session` and `tokens` define the core session and token domain types
- `config` and `context` define the inputs that shape issuance and renewal behavior
- `renewal`, `lease`, and `logout` define the lifecycle transitions and coordination rules
- `repository` defines the persistence contract
- `services` wires those pieces into issue, renew, and revoke workflows
- `errors` defines the session-layer failure model

## Services

The crate exposes three primary service types:

- `SessionIssuer`
- `SessionRenewer`
- `SessionRevoker`

These services stay transport-agnostic so they can be called from HTTP adapters, CLI tools, workers, or other integration layers.

### Minimal session lifecycle

The three services map to the three lifecycle transitions a session-backed auth flow needs:

```rust,ignore
use std::time::SystemTime;
use webgates_sessions::config::SessionConfig;
use webgates_sessions::logout::LogoutRequest;
use webgates_sessions::services::{SessionIssuer, SessionRenewer, SessionRevoker};

// Issue: called on successful login.
let issued = session_issuer.issue_session("user@example.com", SystemTime::now()).await?;

// Renew: called when the client presents a refresh token.
let renewed = session_renewer.renew_session(renewal_context).await?;

// Revoke: called on logout.
let outcome = session_revoker.revoke_session(LogoutRequest::current_session(session_id)).await?;
```

For a complete working HTTP composition, see `webgates-axum`.

## Repository model

Applications provide a `SessionRepository` implementation to persist session state.

The repository contract covers:

- session creation
- session lookup by refresh-token hash
- session and family lookup
- refresh-record lookup
- renewal lease acquisition
- atomic refresh-token rotation
- current-session revocation
- family revocation
- session touch updates

For local development and tests, use the in-memory repository from `webgates-repositories`.
For persistent storage, use backend adapters such as the session repository support in `webgates-repositories`.

## Typical responsibilities

This crate owns:

- session and session-family identifiers and records
- auth and refresh-token issuance primitives
- refresh-token hashing helpers
- renewal decision types and lease state
- repository traits for session creation, lookup, rotation, touch, and revocation
- service-layer workflows for issue, renew, and revoke operations

This crate does not own:

- HTTP cookie extraction
- HTTP response cookie writing
- framework middleware wiring
- route parsing or status-code mapping

Those concerns belong in adapter crates such as `webgates-axum`.

## Integration with Axum

For Axum applications, keep this crate in the core layer and use `webgates-axum` for the HTTP boundary.

Typical Axum composition includes:

- `webgates::authn::SessionLoginService` for session-backed login
- `webgates::authn::SessionLogoutService` for session-backed logout
- `webgates_axum::route_handlers::login_with_sessions`
- `webgates_axum::route_handlers::logout_with_sessions`
- `webgates_axum::session::CookieSessionLayer`

This keeps cookie extraction and `Set-Cookie` mutation in the Axum adapter while renewal rules and revocation semantics remain here.

## Distributed deployment model

Use the same lifecycle for both single-node and distributed deployments:

- **Auth authority**: owns login, refresh-token session state, renewal, logout, and access-token minting
- **Resource services**: validate short-lived access tokens locally and enforce authorization
- **Single-node deployment**: runs both roles in one process

This keeps the public behavior identical across deployment modes while limiting cross-node coupling. Revocation consistency is bounded by the short access-token TTL.

## Security notes

- use persistent signing keys in production
- keep auth tokens short-lived
- treat refresh tokens as opaque high-entropy secrets
- store refresh tokens only as hashes on the server side
- rotate refresh tokens on successful renewal
- revoke the affected session family when replay is detected
- avoid logging raw auth tokens, refresh tokens, or secret material
- keep adapter cookies `HttpOnly`, `Secure`, and narrowly scoped where possible

## Recommended onboarding path

If you are new to this crate, I recommend this order:

1. `session`
2. `tokens`
3. `config`
4. `renewal`
5. `repository`
6. `services`
7. `logout` and `lease`

## Validation

Typical validation commands for this crate:

- `cargo test -p webgates-sessions`
- `cargo test --doc -p webgates-sessions`

## Which crate should you use?

- use `webgates-sessions` when you need the session lifecycle and renewal layer directly
- use `webgates` when you want the higher-level application-facing composition crate
- use `webgates-axum` when you want Axum transport integration for session-backed flows
- use `webgates-repositories` when you need repository implementations for session persistence

## Related crates

- `webgates` - user-facing composition crate
- `webgates-axum` - Axum adapter layer
- `webgates-repositories` - repository implementations and storage backends
- `webgates-codecs` - auth-token codecs
- `webgates-secrets` - hashing and secret primitives

## License

MIT

For the distributed deployment operations guide, see `docs/distributed-sessions.md` in the repository root.