crates.io ↗

iet-auth-session-opaque

feature implementation official

Issues random opaque session keys; storage and transport are selected separately.

CoreFeaturesIntegrationsStacksTooling
Used byno framework crate yetexamples/htmx-starterexamples/skills-only-appexamples/skills-only-app-task-tracker
iet-auth-session-opaqueimplementationOpaque session mechanism
Depends oniet-telemetrycontractiet-authcontractiet-corecontractiet-configcontractiet-config-macroscontract

How to use it

iet-auth-session-opaque issues random opaque session keys and validates them through a selected SessionStore, implementing TokenIssuer, Authenticate, and Invalidate. The token is the credential, so storage (cache-backed, database-backed) and transport (bearer header, cookie) are chosen independently and plug into the same port.

rust
// crates/features/iet-auth-session-opaque/src/lib.rs
use iet_auth::{Authenticate, Invalidate, TokenIssuer};
use iet_auth_session_opaque::{Sessions, config::SessionConfig};
use iet_core::Principal;

// `store` is any SessionStore, e.g. iet-auth-session-cache or -timescale.
let sessions = Sessions::new(store, SessionConfig { ttl_seconds: 3600 })?;

let identity = Principal { subject: "user".into(), profile: Some("buyer".into()) };
let token = sessions.issue(&identity).await?;        // 43-char URL-safe key
assert_eq!(sessions.authenticate(&token).await?, identity);
sessions.invalidate(&token).await?;                  // durable, idempotent revoke
  • Tokens are 32 random bytes encoded as a 43-character URL-safe key; only their SHA-256 digest is stored.
  • invalidate delegates to the store's revoke, so a failed revoke must not be treated as a successful logout.
  • Expiry is enforced during authenticate regardless of the store's behavior.

How it works

issue generates 32 random bytes, stores a SessionRecord under their SHA-256 digest, and returns the URL-safe token; authenticate re-hashes the token, loads the record, checks expiry, and returns its identity; invalidate revokes that digest.

sequenceDiagram
  participant C as "Caller"
  participant S as "Sessions"
  participant T as "SessionStore"
  C->>S: "issue identity"
  S->>S: "random 32 bytes"
  S->>T: "insert sha256 digest record"
  S-->>C: "Secret 43 char token"
  C->>S: "authenticate token"
  S->>T: "find sha256 digest"
  T-->>S: "SessionRecord or None"
  S-->>C: "Principal or session.invalid"
  C->>S: "invalidate token"
  S->>T: "revoke sha256 digest"

What it implements

  • Implements iet_auth::TokenIssuer from iet-auth.
  • Implements iet_auth::Authenticate<Secret<String>> from iet-auth.
  • Implements iet_auth::Invalidate<Secret<String>> from iet-auth.

What's inside

Modules

  • src/config.rs
  • src/lib.rs

Public API

(root)

  • struct Sessions
  • pub fn new(store: S, config: config::SessionConfig) -> AppResult<Self>

config

  • struct SessionConfig

Impl map

  • TokenIssuer for Sessions<S>
  • Authenticate<Secret<String>> for Sessions<S>
  • Invalidate<Secret<String>> for Sessions<S>

Depends on

External crates: base64, rand_core, sha2

Used by

  • No other framework crate depends on it directly.

In this repository

  • examples/htmx-starter
  • examples/skills-only-app
  • examples/skills-only-app-task-tracker

Source: crates/features/iet-auth-session-opaque