pub trait ApprovalStore: Send + Sync {
// Required methods
fn store_pending(
&self,
request: &ApprovalRequest,
) -> Result<(), ApprovalStoreError>;
fn get_pending(
&self,
id: &str,
) -> Result<Option<ApprovalRequest>, ApprovalStoreError>;
fn list_pending(
&self,
filter: &ApprovalFilter,
) -> Result<Vec<ApprovalRequest>, ApprovalStoreError>;
fn resolve(
&self,
id: &str,
decision: &ApprovalDecision,
) -> Result<(), ApprovalStoreError>;
fn count_approved(
&self,
subject_id: &str,
policy_id: &str,
) -> Result<u64, ApprovalStoreError>;
fn record_consumed(
&self,
token_id: &str,
parameter_hash: &str,
now: u64,
) -> Result<(), ApprovalStoreError>;
fn is_consumed(
&self,
token_id: &str,
parameter_hash: &str,
) -> Result<bool, ApprovalStoreError>;
fn get_resolution(
&self,
id: &str,
) -> Result<Option<ResolvedApproval>, ApprovalStoreError>;
}Expand description
Persistent store for pending and resolved HITL approvals. The trait
is intentionally synchronous because every concrete implementation
in the kernel hot path today (in-memory, SQLite via rusqlite) is
synchronous, and the kernel itself does not run on an async
executor.
Required Methods§
Sourcefn store_pending(
&self,
request: &ApprovalRequest,
) -> Result<(), ApprovalStoreError>
fn store_pending( &self, request: &ApprovalRequest, ) -> Result<(), ApprovalStoreError>
Persist a new pending request. Idempotent on approval_id: a
second call with the same id returns without error as long as
the stored payload matches.
Sourcefn get_pending(
&self,
id: &str,
) -> Result<Option<ApprovalRequest>, ApprovalStoreError>
fn get_pending( &self, id: &str, ) -> Result<Option<ApprovalRequest>, ApprovalStoreError>
Fetch a single pending approval by id.
Sourcefn list_pending(
&self,
filter: &ApprovalFilter,
) -> Result<Vec<ApprovalRequest>, ApprovalStoreError>
fn list_pending( &self, filter: &ApprovalFilter, ) -> Result<Vec<ApprovalRequest>, ApprovalStoreError>
List all pending approvals matching the filter.
Sourcefn resolve(
&self,
id: &str,
decision: &ApprovalDecision,
) -> Result<(), ApprovalStoreError>
fn resolve( &self, id: &str, decision: &ApprovalDecision, ) -> Result<(), ApprovalStoreError>
Mark a pending approval as resolved. Returns
ApprovalStoreError::AlreadyResolved if the request has already
been resolved (double-resolve protection) and
ApprovalStoreError::Replay if the bound token has already been
consumed on a different request.
Sourcefn count_approved(
&self,
subject_id: &str,
policy_id: &str,
) -> Result<u64, ApprovalStoreError>
fn count_approved( &self, subject_id: &str, policy_id: &str, ) -> Result<u64, ApprovalStoreError>
Count approved calls for a given subject / grant pair. Used by
Constraint::RequireApprovalAbove threshold accounting.
Sourcefn record_consumed(
&self,
token_id: &str,
parameter_hash: &str,
now: u64,
) -> Result<(), ApprovalStoreError>
fn record_consumed( &self, token_id: &str, parameter_hash: &str, now: u64, ) -> Result<(), ApprovalStoreError>
Record that a token (by token_id and parameter_hash) has
been consumed. Used to reject replays of the same approval
token across a restart. Implementations may also call this from
[resolve]; exposing it on the trait lets the kernel do the
replay check before persisting the resolution, which matters
when the store is backed by SQLite and wants to run the check
inside the transaction.
Sourcefn is_consumed(
&self,
token_id: &str,
parameter_hash: &str,
) -> Result<bool, ApprovalStoreError>
fn is_consumed( &self, token_id: &str, parameter_hash: &str, ) -> Result<bool, ApprovalStoreError>
Returns true if the token has already been consumed.
Sourcefn get_resolution(
&self,
id: &str,
) -> Result<Option<ResolvedApproval>, ApprovalStoreError>
fn get_resolution( &self, id: &str, ) -> Result<Option<ResolvedApproval>, ApprovalStoreError>
Fetch the resolution record for a previously resolved approval.