pub struct Session {Show 14 fields
pub session_id: String,
pub did: String,
pub challenge: String,
pub state: SessionState,
pub created_at: u64,
pub last_seen: u64,
pub refresh_token: Option<String>,
pub refresh_expires_at: Option<u64>,
pub tee_attested: bool,
pub amr: Vec<String>,
pub acr: String,
pub acr_expires_at: Option<u64>,
pub token_id: Option<String>,
pub session_pubkey_b58btc: Option<String>,
}Expand description
A session record stored in fjall under session:{session_id}.
Debug is hand-written below to redact the refresh_token. The raw
derive would render it inline — any tracing::debug!("{session:?}"),
panic backtrace, or dbg!() call holding a Session would otherwise
exfiltrate a bearer-equivalent secret to logs.
Fields§
§session_id: String§did: String§challenge: String§state: SessionState§created_at: u64§last_seen: u64Wall-clock epoch seconds of the most recent authenticated request on
this session. Intrinsic-sender (DIDComm/TSP) sessions carry no refresh
token, so this drives their idle-TTL expiry in
cleanup_expired_sessions. REST sessions set it too but are bounded
by refresh_expires_at. #[serde(default)] so rows written before this
field existed deserialise with 0; the sweeper falls back to
created_at in that case.
refresh_token: Option<String>§refresh_expires_at: Option<u64>§tee_attested: boolWhether the challenge issued for this session was accompanied
by a successful TEE attestation. Distinct from “this VTA was built
with the TEE feature”: a TEE binary running in TeeMode::Optional
can serve unattested challenges when the provider errors out, and
the resulting JWT must reflect that.
#[serde(default)] so older session records (written before this
field existed) deserialize as false — the conservative default.
amr: Vec<String>AAL claims persisted across token rotation. Mirrors the JWT’s
amr / acr so [/auth/refresh] mints a new access token at
the same authentication-method-references and assurance level
the session was last issued at. Without this, a session that
was step-upped to aal2 would be silently dropped back to
aal1 on every 15-minute refresh.
#[serde(default)] on both: a session row written before this
field landed deserialises with empty vectors / empty string,
which the refresh handler treats as “unknown AAL — fall back
to aal1”. Same behaviour as pre-migration; the holder can
re-step-up if needed.
acr: String§acr_expires_at: Option<u64>Epoch-seconds deadline after which a step-up-elevated acr lapses back
to aal1. Set when a step-up elevates the session; read by the
intrinsic-sender resolver (resolve_did_session), which downgrades on
read once the window closes. None for an un-elevated session — and, in
this phase, for REST sessions, whose short access-token TTL already
bounds elevation (a later phase wires REST into the same read-time
downgrade). #[serde(default)] for back-compat with pre-existing rows.
token_id: Option<String>JWT jti rotation pin. Set per-token-issue so old JWTs are
immediately invalidated when a new token is minted for the
same session — the AuthClaims extractor compares the JWT’s
jti against this field and rejects mismatches.
Optional because not every consumer uses per-token-issue
rotation; the canonical extractor checks this only when
Some(_). #[skip_serializing_if = "Option::is_none"]
keeps the field out of the serialised form when unused so
existing storage rows do not gain a token_id: null column.
session_pubkey_b58btc: Option<String>Ephemeral session pubkey for Data Integrity proof binding
(eddsa-jcs-2022). Ed25519 multikey, base58btc with the
z prefix (e.g. z6MkfBwQrx…). The corresponding
did:key:<this> is the verificationMethod the holder uses
when signing trust-task envelopes for this session.
None for clients that did not register a session pubkey;
REQUIRED-spec dispatch then rejects proofless envelopes per
the trust-task framework’s IS_PROOF_REQUIRED gate.
Trait Implementations§
Source§impl<'de> Deserialize<'de> for Session
impl<'de> Deserialize<'de> for Session
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Auto Trait Implementations§
impl Freeze for Session
impl RefUnwindSafe for Session
impl Send for Session
impl Sync for Session
impl Unpin for Session
impl UnsafeUnpin for Session
impl UnwindSafe for Session
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> BorrowUnordered for T
impl<T> BorrowUnordered for T
fn as_unordered(&self) -> &Unordered<T>
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<'de, T, C> DeserializeTyped<'de, C> for Twhere
T: Deserialize<'de>,
impl<'de, T, C> DeserializeTyped<'de, C> for Twhere
T: Deserialize<'de>,
fn deserialize_typed<S>(
_: &C,
deserializer: S,
) -> Result<T, <S as Deserializer<'de>>::Error>where
S: Deserializer<'de>,
impl<T, U> DeserializeTypedOwned<T> for Uwhere
U: for<'de> DeserializeTyped<'de, T>,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T, U, C> IntoWithContext<U, C> for Twhere
U: FromWithContext<T, C>,
impl<T, U, C> IntoWithContext<U, C> for Twhere
U: FromWithContext<T, C>,
Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<T> ResourceProvider<()> for T
impl<T> ResourceProvider<()> for T
Source§fn get_resource(&self) -> &()
fn get_resource(&self) -> &()
T.