pub struct SecureAgent<S: AgentState> { /* private fields */ }Expand description
A secure agent that ties together typestate, policy engines, and capabilities.
S is the typestate parameter: Unauthenticated or Authenticated.
§Why a newtype wrapper?
typesec-core’s Agent is the minimal typestate foundation. SecureAgent
adds the async request_capability and execute methods on top, keeping
the core crate dependency-free (no tokio).
Implementations§
Source§impl SecureAgent<Unauthenticated>
impl SecureAgent<Unauthenticated>
Sourcepub fn new(engine: Arc<dyn PolicyEngine>) -> Self
pub fn new(engine: Arc<dyn PolicyEngine>) -> Self
Create a new unauthenticated agent with the given policy engine.
Sourcepub fn authenticate(
self,
credentials: Credentials,
) -> Result<SecureAgent<Authenticated>, AgentError>
pub fn authenticate( self, credentials: Credentials, ) -> Result<SecureAgent<Authenticated>, AgentError>
Authenticate the agent.
On success, returns SecureAgent<Authenticated>. The unauthenticated
agent is consumed — you can’t hold onto the unauthenticated handle
after calling this.
Source§impl SecureAgent<Authenticated>
impl SecureAgent<Authenticated>
Sourcepub fn engine(&self) -> Arc<dyn PolicyEngine>
pub fn engine(&self) -> Arc<dyn PolicyEngine>
Access the underlying policy engine.
Useful for composing raw check() calls alongside capability-based access.
Sourcepub async fn request_capability<P: Permission, R: Resource>(
&self,
resource: &R,
) -> Result<Capability<P, R>, CapabilityError>
pub async fn request_capability<P: Permission, R: Resource>( &self, resource: &R, ) -> Result<Capability<P, R>, CapabilityError>
Request a capability for permission P on resource.
This is the only way to obtain a Capability<P, R> from outside
typesec-core. The policy engine is called, the decision is logged,
and either a capability or an error is returned.
The capability is a zero-sized proof token — holding it means the policy engine approved the request at the time of this call.
Sourcepub async fn execute<P, R, F, Fut>(
&self,
cap: &Capability<P, R>,
resource: &R,
action: F,
) -> Result<(), TaskError>
pub async fn execute<P, R, F, Fut>( &self, cap: &Capability<P, R>, resource: &R, action: F, ) -> Result<(), TaskError>
Execute an async action, requiring a valid capability as proof.
The key design point: execute takes cap: &Capability<P, R> as an
argument. There is no code path through execute that doesn’t hold a
capability. If you don’t have a capability, you can’t call this method
(the type system ensures it).
This is different from:
// ❌ Guard-based — the check can be skipped, the condition forgotten.
if has_permission { do_thing(); }
// ✅ Capability-based — the capability IS the check.
agent.execute(&cap, &resource, action).await?;