pub struct OwnerCapability {
pub format_version: u32,
pub owner_id: Vec<u8>,
pub issuer_state_hash: Vec<u8>,
pub parent_capability_id: Vec<u8>,
pub subject: Option<CapabilityPrincipal>,
pub grants: Vec<SpoolCapabilityGrant>,
pub not_before_unix_seconds: i64,
pub expires_at_unix_seconds: i64,
pub nonce: Vec<u8>,
pub capability_id: Vec<u8>,
}Expand description
V1 canonicalization and signature remain unchanged. The alpha.5 format-2 timeline grant is a hard cut: reject it. For format_version=3, canonical_owner_capability_v3 uses the v1 field order and encodings, but every grant appends one presence byte after action (exactly 0x01) followed by scope fields 1..6. Byte fields are counted; credential_identity uses precisely the origin transcript’s tag (0x01 or 0x02) and counted IDs, not a protobuf serialization; class is u32be. The scope is included both with and without capability_id. The v3 capability_id is SHA-256( UTF8(“heddle-owner-capability-v3”) || canonical body without capability_id); its owner signature is Ed25519 over SHA-256 of that domain followed by the canonical body WITH capability_id. The v1 domain and body never change. Unknown fields and unsupported versions fail closed. A v3 chain is direct (parent_capability_id empty), has one signed capability and a single-block subject Biscuit bound to its exact subject key/kind/ID and grant. Its authority block has the v1 owner_subject, owner_capability, owner_validity facts plus exactly one owner_timeline_accept_server(“<spool_uuid_hex>”, “<path_hex>”, “<principal_uuid_hex>”, “<credential_id_hex>”, “<pop_sha256_hex>”, <class_u32>, “<thread_id_hex>”, “<origin_sha256_hex>”) OR owner_timeline_accept_offline(“<spool_uuid_hex>”, “<path_hex>”, “<principal_uuid_hex>”, “<issued_ancestor_credential_id_hex>”, “<terminal_revocation_id_hex>”, “<derivation_path_sha256_hex>”, “<pop_sha256_hex>”, <class_u32>, “<thread_id_hex>”, “<origin_sha256_hex>”) fact, selected exactly by the original credential_identity variant. IDs are lowercase raw-byte hex only inside this Biscuit fact; path_hex is the v1 u32-length-prefixed canonical path segments as lower-case hex. Reject extra facts, attenuation blocks, duplicate grants and any PURGE fact; this direct exact grant cannot be widened by a later block. The grant selector MUST equal the actual canonical Spool UUID/path and MUST have include_descendants=false. V1 PURGE verifiers reject v3 rather than treating this action as purge or ordinary spool-write authority.
Fields§
§format_version: u321 for PURGE or 3 for exact-subject timeline acceptance.
owner_id: Vec<u8>§issuer_state_hash: Vec<u8>§parent_capability_id: Vec<u8>Empty only for a direct owner grant.
subject: Option<CapabilityPrincipal>§grants: Vec<SpoolCapabilityGrant>§not_before_unix_seconds: i64§expires_at_unix_seconds: i64§nonce: Vec<u8>Exactly 32 random bytes.
capability_id: Vec<u8>Recomputed from the matching canonical v1/v3 body without capability_id.
Trait Implementations§
Source§impl Clone for OwnerCapability
impl Clone for OwnerCapability
Source§fn clone(&self) -> OwnerCapability
fn clone(&self) -> OwnerCapability
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 OwnerCapability
impl Debug for OwnerCapability
Source§impl Default for OwnerCapability
impl Default for OwnerCapability
Source§fn default() -> OwnerCapability
fn default() -> OwnerCapability
Source§impl Message for OwnerCapability
impl Message for OwnerCapability
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.Source§impl PartialEq for OwnerCapability
impl PartialEq for OwnerCapability
impl StructuralPartialEq for OwnerCapability
Auto Trait Implementations§
impl Freeze for OwnerCapability
impl RefUnwindSafe for OwnerCapability
impl Send for OwnerCapability
impl Sync for OwnerCapability
impl Unpin for OwnerCapability
impl UnsafeUnpin for OwnerCapability
impl UnwindSafe for OwnerCapability
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
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,
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> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more