pub struct AccessTokenResponse {
pub token: String,
pub subject: String,
pub expires_at: Option<Timestamp>,
pub session_id: String,
pub amr: Vec<String>,
pub credential_id: String,
pub grant_envelope: Vec<u8>,
pub owner_authorization: Option<OwnerAuthorizationBundle>,
pub device_id: String,
}Fields§
§token: StringThe Biscuit (base64url-encoded). Goes in the heddle_session
cookie for browser flows and in the CLI credentials store for
device-bound flows. Empty when weft does not mint; clients mint
from the other fields, including device_id.
subject: String§expires_at: Option<Timestamp>Unix-seconds expiry. The Biscuit also carries this internally, but exposing it explicitly lets clients know when to renew without parsing the token.
session_id: StringThe Biscuit’s session() fact (also its revocation id). Stable
public id surfaced in the Active Sessions UI; argument to
RevokeSession.
amr: Vec<String>§credential_id: Stringissued_credentials.id for tokens minted from a long-lived
credential row (device, service-account, agent). Empty for
browser sessions.
grant_envelope: Vec<u8>Server-signed GrantEnvelope v2 paired with a client-minted Biscuit. It is not owner authority; ordinary spool operations are authorized by the resulting transport Biscuit. The field contains the following byte-exact wire value:
canonical_payload_v2 || signature[64]
signature is raw Ed25519 and covers every byte of
canonical_payload_v2. All integers are big-endian; strings are UTF-8:
bytes “heddle-grant-envelope-v2\0” (signed domain prefix) u8 format_version (MUST equal 0x02; this byte is signed) bytes “biscuit_authority_public_key\0” 32 bytes biscuit_authority_public_key bytes “device_proof_public_key\0” 32 bytes device_proof_public_key u16 + N subject (N <= 256) u16 rights_count (<= 64) repeated in encoded order: u16 + N kind (N <= 1024) u16 + N path (N <= 1024) u16 + N action (N <= 1024) i64 issued_at (Unix seconds) i64 expires_at (Unix seconds)
The exact domain, discriminator, and both role labels are inside the server-signed payload. A parser MUST require the domain, 0x02, both labels in this order, two distinct fixed-length keys, and complete input with no trailing bytes. An issuer MUST reject equal role keys. After cutover a parser MUST reject the one-key v1 envelope; field presence MUST NOT select a version or provide a compatibility fallback.
The Biscuit minted under biscuit_authority_public_key remains the exact
byte prefix of every attenuation. Each ordinary post-authority delegating
block appends one verified pop_delegation transition rooted at
device_proof_public_key; an implementation must never rebuild or replace
the original client-minted prefix when attenuating. Tier-1 request signing
is leaf-only: after any accepted pop_delegation, only the effective leaf
proof key may sign; signatures by ancestor proof keys or by the Biscuit
authority key MUST be rejected.
Owner-authored purge-only bundle returned without re-signing or reinterpretation. It grants no redact, visibility, or metadata authority.
device_id: StringPersisted device_roots.id after RegisterPublicKey. Clients set
MintParams.device_id from this field without reading Postgres. This
is a mint input, not capability: it identifies the device root used
when the client mints after weft leaves token empty.
Trait Implementations§
Source§impl Clone for AccessTokenResponse
impl Clone for AccessTokenResponse
Source§fn clone(&self) -> AccessTokenResponse
fn clone(&self) -> AccessTokenResponse
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for AccessTokenResponse
impl Debug for AccessTokenResponse
Source§impl Default for AccessTokenResponse
impl Default for AccessTokenResponse
Source§impl Message for AccessTokenResponse
impl Message for AccessTokenResponse
Source§fn encoded_len(&self) -> usize
fn encoded_len(&self) -> usize
Source§fn encode(&self, buf: &mut impl BufMut) -> Result<(), EncodeError>where
Self: Sized,
fn encode(&self, buf: &mut impl BufMut) -> Result<(), EncodeError>where
Self: Sized,
Source§fn encode_to_vec(&self) -> Vec<u8> ⓘwhere
Self: Sized,
fn encode_to_vec(&self) -> Vec<u8> ⓘwhere
Self: Sized,
Source§fn encode_length_delimited(
&self,
buf: &mut impl BufMut,
) -> Result<(), EncodeError>where
Self: Sized,
fn encode_length_delimited(
&self,
buf: &mut impl BufMut,
) -> Result<(), EncodeError>where
Self: Sized,
Source§fn encode_length_delimited_to_vec(&self) -> Vec<u8> ⓘwhere
Self: Sized,
fn encode_length_delimited_to_vec(&self) -> Vec<u8> ⓘwhere
Self: Sized,
Source§fn decode(buf: impl Buf) -> Result<Self, DecodeError>where
Self: Default,
fn decode(buf: impl Buf) -> Result<Self, DecodeError>where
Self: Default,
Source§fn decode_length_delimited(buf: impl Buf) -> Result<Self, DecodeError>where
Self: Default,
fn decode_length_delimited(buf: impl Buf) -> Result<Self, DecodeError>where
Self: Default,
Source§fn merge(&mut self, buf: impl Buf) -> Result<(), DecodeError>where
Self: Sized,
fn merge(&mut self, buf: impl Buf) -> Result<(), DecodeError>where
Self: Sized,
self. Read moreSource§fn merge_length_delimited(&mut self, buf: impl Buf) -> Result<(), DecodeError>where
Self: Sized,
fn merge_length_delimited(&mut self, buf: impl Buf) -> Result<(), DecodeError>where
Self: Sized,
self.