pub struct AgentKey { /* private fields */ }Expand description
A short-lived per-agent keypair, signed by the user’s root key.
AgentKey deliberately omits any save/load API: agent keys live
in memory for the lifetime of the agent process and are
regenerated on restart. The certificate (AgentKey::cert)
stores enough provenance for peers to trust the public half.
Implementations§
Source§impl AgentKey
impl AgentKey
Sourcepub fn issue(user: &UserKey, metadata: AgentMetadata) -> Self
pub fn issue(user: &UserKey, metadata: AgentMetadata) -> Self
Issue a new agent key, signed by the given user.
The user’s private key is used exactly once here to sign
(agent_pubkey || canonical_metadata_bytes), producing the
issuer_sig of the embedded CertChain (a root Issuer::User).
Use AgentKey::delegate to mint an attenuated sub-agent.
Sourcepub fn delegate(&self, metadata: AgentMetadata) -> Result<Self>
pub fn delegate(&self, metadata: AgentMetadata) -> Result<Self>
Delegate a sub-agent key from this agent — attenuation-only.
The child’s caveats must be ⊑ this agent’s caveats (the parent
authority), otherwise MeshError::CaveatAmplification is returned
and no key is minted. The sub-cert is signed by this agent’s key and
embeds this agent’s cert as its parent, so it roots at the same user
and every verifier re-checks attenuation at each link. A confused or
compromised agent therefore cannot mint a child with more authority
than it holds.
Sourcepub fn possession_challenge(
&self,
subject_pubkey: [u8; 32],
) -> PossessionChallenge
pub fn possession_challenge( &self, subject_pubkey: [u8; 32], ) -> PossessionChallenge
Issue a PossessionChallenge for certifying subject_pubkey under this
agent (§9.2). The certifier holds the returned challenge, sends it to the
subject out of band, and passes the subject’s signed answer back into
delegate_external. The nonce is fresh, so each
challenge is single-use.
Sourcepub fn delegate_external(
&self,
challenge: &PossessionChallenge,
proof: &Signature,
metadata: AgentMetadata,
) -> Result<CertChain>
pub fn delegate_external( &self, challenge: &PossessionChallenge, proof: &Signature, metadata: AgentMetadata, ) -> Result<CertChain>
Certify an externally-held public key into a CertChain signed by
this agent — attenuation-only, without minting or holding the external
party’s secret, and only against a proof of possession (§9.2).
This is the seam phone enrollment needs. A worker agent (itself delegated
from a UserKey) can vouch for a phone’s keystore-resident public key:
it produces a sub-cert rooted at the same user, with caveats ⊑ this
agent’s authority, signed by this agent’s key. The phone never reveals its
private key — it keeps its seed (or a non-exportable keystore handle) and
reconstructs its own AgentKey via
from_seed_and_cert.
Proof of possession. challenge must have been issued by this agent
(via possession_challenge) and proof must
be the subject’s signature over PossessionChallenge::signing_bytes.
Without this, an agent could certify any pubkey — a victim’s, or one it
does not control — which a cross-cloud join must never allow. The cert is
minted over challenge.subject_pubkey.
§Errors
MeshError::InvalidCertChainifchallenge.issuer_pubkeyis not this agent (a challenge it did not issue);MeshError::BadSignatureif the PoP does not verify;MeshError::CaveatAmplificationifmetadata’s caveats are not⊑this agent’s, exactly likedelegate.
Sourcepub fn fingerprint(&self) -> Fingerprint
pub fn fingerprint(&self) -> Fingerprint
BLAKE3 fingerprint of the agent’s public key bytes.
Sourcepub fn public_bytes(&self) -> [u8; 32]
pub fn public_bytes(&self) -> [u8; 32]
Raw 32-byte ed25519 public key for this agent.
Sourcepub fn signing_key_bytes(&self) -> [u8; 32]
pub fn signing_key_bytes(&self) -> [u8; 32]
Expose the raw 32-byte ed25519 signing key bytes.
This is the ONLY method that surfaces an agent’s private bytes.
It exists for one reason: the transport layer
(agent-mesh-transport) needs to construct an iroh SecretKey
from the same ed25519 seed so the agent’s pubkey doubles as its
iroh EndpointId. Callers must NOT persist or transmit these
bytes — the agent key is ephemeral by design.
Sourcepub fn from_seed_and_cert(seed: &[u8; 32], cert: CertChain) -> Result<Self>
pub fn from_seed_and_cert(seed: &[u8; 32], cert: CertChain) -> Result<Self>
Reconstruct an AgentKey from a 32-byte ed25519 seed and an
existing cert chain.
Mirror of signing_key_bytes: used
by the PyO3 bindings (and any FFI consumer) to ship an
AgentKey across a tokio-spawn boundary without forcing
Clone on the underlying ed25519 signing key. Returns
MeshError::BadSignature if the seed produces a public key
that doesn’t match the cert chain’s agent_pubkey — i.e.
rejects a forged pairing.
Sourcepub fn verifying_key(&self) -> VerifyingKey
pub fn verifying_key(&self) -> VerifyingKey
The ed25519 verifying (public) half of this agent’s key.
Trait Implementations§
Source§impl MeshSigner for AgentKey
AgentKey is the software (in-memory seed) [MeshSigner]: it signs with
the seed it holds. This is today’s behavior, surfaced through the trait so
the envelope/transport layers can sign via &dyn MeshSigner and a future
non-exportable keystore signer drops in at the same call sites.
impl MeshSigner for AgentKey
AgentKey is the software (in-memory seed) [MeshSigner]: it signs with
the seed it holds. This is today’s behavior, surfaced through the trait so
the envelope/transport layers can sign via &dyn MeshSigner and a future
non-exportable keystore signer drops in at the same call sites.
Source§fn verifying_key(&self) -> VerifyingKey
fn verifying_key(&self) -> VerifyingKey
agent_pubkey of the CertChain it is paired with,
or the resulting signatures will not verify against the cert.