Releases: cirreum/Cirreum.Authentication.SessionTicket
Release list
Release v1.0.4
Full Changelog: v1.0.3...v1.0.4
Release v1.0.3
Release v1.0.2
Release v1.0.1
Release v1.0.0
Cirreum.Authentication.SessionTicket 1.0.0 — First-class session-handoff credentials
Why this release exists
The Cirreum 1.0 Foundation Reset recognizes session-handoff as a first-class authentication pattern. SessionTicket is the scheme for it — a credential that bridges the gap between the authentication context that establishes a session (a REST /negotiate call, a partner webhook, a Twilio inbound flow) and the long-lived connection scope that uses it (WebSocket, SignalR, gRPC streaming).
Cirreum.AuthenticationProvider defines the contracts; this 1.0 release ships their first concrete implementations.
What's in 1.0
Opaque-variant tickets + Bearer transport
The v1 hardening posture: short-TTL opaque tickets + single-use + TLS channel security. The package generates 32-byte cryptographically random hex tickets (optionally prefixed), persists them in an ISessionStore, and atomically consumes them on first successful validation. JWT-variant tickets (RFC 7519 / RFC 8725 / RFC 9068) ship in 1.1.0+.
Composable contracts
The four contracts (ISessionTicketIssuer, ISessionTicketValidator, ISessionStore, ISessionTicketPrincipalBinder) live in Cirreum.AuthenticationProvider so apps can swap any of them independently:
- Custom claim shape? Register your own
ISessionTicketPrincipalBinder. - Distributed deployment? Register a Redis/Cosmos-backed
ISessionStore. - App-specific ticket-value generation? Register your own
ISessionTicketIssuer. - Different validation semantics (reusable tickets, allow-list per partner)? Your own
ISessionTicketValidator.
The package's AddSessionTicket(...) uses TryAddSingleton so any app-side registration wins.
IBearerSchemeSelector dispatch
The package ships SessionTicketAuthenticationSchemeSelector as an IBearerSchemeSelector at SchemeSelectorPriority.Session. The runtime dynamic forward resolver picks SessionTicket when the Authorization: Bearer value carries the configured prefix (or, prefix-less, is non-JWT-shaped).
Quick start
// Composition root — the prefix is the leading segment of the opaque value (st_prod_…)
builder.Services.AddAuthentication()
.AddSessionTicket(bearerPrefix: "st_prod_");
// Negotiate endpoint — app code mints the ticket
app.MapPost("/negotiate", async (HttpContext ctx, ISessionTicketIssuer issuer) => {
var ticket = await issuer.IssueAsync(new SessionTicketIssueRequest {
Subject = ctx.User.Identity!.Name!,
Lifetime = TimeSpan.FromMinutes(2)
}, ctx.RequestAborted);
// Return the opaque value (prefix included) to the client over TLS.
return Results.Ok(new { ticket = ticket.TicketValue, url = "/ws/chat" });
});
// Long-lived endpoint — handler runs at handshake; client sends Authorization: Bearer st_prod_…
app.MapGet("/ws/chat", async ctx => {
/* ... */
}).RequireAuthorization();See MIGRATION-v1.md for the full pattern walkthrough.
How it pairs with the rest of the Authentication pillar
| Package | Role |
|---|---|
Cirreum.Kernel |
INotification markers, versioned-message primitive, auth event bus, AuthenticationContextKeys |
Cirreum.AuthenticationProvider |
ISessionTicketIssuer/Validator/Store/PrincipalBinder, ISchemeSelector |
Cirreum.Authentication.SessionTicket (this release) |
Opaque-variant + Bearer transport + in-memory store + scheme handler |
Cirreum.Runtime.AuthenticationProvider |
Dynamic forward resolver, selector iteration |
Cirreum.Runtime.Authentication |
App-facing AddAuthentication(...) builder |
Compatibility
- .NET 10.0 target.
- Cirreum.Providers 1.2.0+ required.
- Cirreum.AuthenticationProvider 1.0.0+ required.
- No predecessor package — initial release.