pub struct Grant {Show 13 fields
pub grant_id: String,
pub grantor: String,
pub scope: Vec<String>,
pub audience: String,
pub parent_request_id: Option<String>,
pub delegation_depth: u32,
pub issued_at: String,
pub expiry: String,
pub max_delegation: u32,
pub objective_hash: Option<String>,
pub issuer_sig: Option<String>,
pub parent_grant_id: Option<String>,
pub grantee: Option<String>,
}Expand description
A signed capability grant. Each delegation edge mints a narrower grant, signed by the grantor, so a verifier can walk grant -> parent-grant -> … -> root offline. Canonical binding mirrors the invitation statement: a pipe-delimited, version-prefixed line with variable-length fields folded into digests, so the canonical stays single-line and unambiguous.
Fields§
§grant_id: String§grantor: StringEd25519 pubkey of the grantor, base64url-no-pad.
scope: Vec<String>§audience: String§parent_request_id: Option<String>§delegation_depth: u32§issued_at: String§expiry: String§max_delegation: u32§objective_hash: Option<String>§issuer_sig: Option<String>Grantor’s detached signature over this grant’s canonical bytes.
Deliberately absent from canonical_for_signing – a signature cannot
cover itself. Required for any grant carried in a mandate chain;
resolve_grant_chain refuses unsigned ancestors.
parent_grant_id: Option<String>Content id of the grant this one was delegated from. None marks a
root grant. Signed, so lineage cannot be re-parented after issuance –
and because ids are content-derived, this is a hash commitment to the
exact parent, not a reference to a name someone else could also claim.
grantee: Option<String>Base64url-no-pad Ed25519 public key of the agent entitled to exercise this grant. Signed, so a holder cannot rebind it to themselves.
None makes the grant a bearer credential: whoever holds the bytes
holds the authority. That was the only mode before this field existed,
and it is why a grant file copied into another workspace let a different
key emit a receipt claiming its authority with nothing to object –
grantor says who issued it and audience says which system it acts
against, but nothing said who was allowed to spend it.
Verification treats absence as a disclosed weakness, not a pass: see
Grant::binds_holder.
Implementations§
Source§impl Grant
impl Grant
Sourcepub fn canonical_for_signing(&self) -> String
pub fn canonical_for_signing(&self) -> String
Canonical signing bytes. v1|grant| prefixed; the variable-length
scope is folded into a sorted-key JSON digest so the line stays
single-field-per-position. New fields go through a canonical-version
bump, never a silent extension.
Sourcepub fn binds_holder(&self) -> bool
pub fn binds_holder(&self) -> bool
Whether this grant names the key allowed to exercise it.
false means bearer: authentic, verifiable, and spendable by anyone who
obtains the bytes. Callers must surface that rather than treat a valid
signature as sufficient – the signature proves who issued the grant,
never who is entitled to use it.
Sourcepub fn exercisable_by(&self, holder_pubkey: &str) -> bool
pub fn exercisable_by(&self, holder_pubkey: &str) -> bool
Whether holder_pubkey (base64url-no-pad Ed25519) may exercise this
grant. A bearer grant returns true for every key, which is exactly the
property Grant::binds_holder exists to let callers warn about.
Sourcepub fn derive_grant_id(&self) -> String
pub fn derive_grant_id(&self) -> String
The grant’s content id: grn_ + first 16 hex of sha256 over the
canonical bytes. Mirrors artifact_id = "art_" + hex(sha256(PAE))[..16].
Ids stop being claims and become facts: two grants collide only under a
hash break, and a parent_grant_id therefore commits to one specific
parent rather than to whatever grant happens to assert that name.
Sourcepub fn id_is_consistent(&self) -> bool
pub fn id_is_consistent(&self) -> bool
True when the declared grant_id matches the derived one. A mismatch
means the id was chosen rather than computed, so nothing that
references it by id can be trusted to reference this grant.
Sourcepub fn sign_canonical(&self, signer: &dyn Signer) -> Result<String, SignerError>
pub fn sign_canonical(&self, signer: &dyn Signer) -> Result<String, SignerError>
Sign the grant’s canonical bytes; returns the base64url-no-pad
signature. The grantor field must be signer’s public key for the
grant to later verify.
Sourcepub fn verify_canonical(&self, signature_b64url: &str) -> bool
pub fn verify_canonical(&self, signature_b64url: &str) -> bool
Verify signature_b64url against self.grantor over the canonical
bytes. Returns true only when the pubkey decodes AND the signature
math checks out. Does not consult trust roots – the caller decides
whether grantor is a pinned issuer.
Trait Implementations§
Source§impl<'de> Deserialize<'de> for Grant
impl<'de> Deserialize<'de> for Grant
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>,
impl Eq for Grant
impl StructuralPartialEq for Grant
Auto Trait Implementations§
impl Freeze for Grant
impl RefUnwindSafe for Grant
impl Send for Grant
impl Sync for Grant
impl Unpin for Grant
impl UnsafeUnpin for Grant
impl UnwindSafe for Grant
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> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.