<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ekin Yegül</title>
    <description>The latest articles on DEV Community by Ekin Yegül (@fintechbear).</description>
    <link>https://dev.to/fintechbear</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4222449%2F0f4dbf0a-41d7-4a01-b639-bc6c5f809d00.jpg</url>
      <title>DEV Community: Ekin Yegül</title>
      <link>https://dev.to/fintechbear</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fintechbear"/>
    <language>en</language>
    <item>
      <title>A Signed Mandate Is Not Authorization: A Rust SDK for AI-Agent Transactions</title>
      <dc:creator>Ekin Yegül</dc:creator>
      <pubDate>Mon, 02 Nov 2026 13:17:38 +0000</pubDate>
      <link>https://dev.to/fintechbear/a-signed-mandate-is-not-authorization-a-rust-sdk-for-ai-agent-transactions-2me0</link>
      <guid>https://dev.to/fintechbear/a-signed-mandate-is-not-authorization-a-rust-sdk-for-ai-agent-transactions-2me0</guid>
      <description>&lt;h1&gt;
  
  
  A Signed Mandate Is Not Authorization: A Rust SDK for AI-Agent Transactions
&lt;/h1&gt;

&lt;p&gt;An AI agent submits a $50 transfer request.&lt;/p&gt;

&lt;p&gt;Its mandate has a valid Ed25519 signature. The signed scope permits transfers up to $100 per transaction. The requested amount is below that limit.&lt;/p&gt;

&lt;p&gt;Would you authorize the payment?&lt;/p&gt;

&lt;p&gt;Not yet.&lt;/p&gt;

&lt;p&gt;The signature and the amount check establish useful facts. Neither establishes whether the delegation has been revoked, whether the agent has already exhausted a cumulative budget, or whether the request has been processed before.&lt;/p&gt;

&lt;p&gt;That distinction matters when designing authorization boundaries for AI agents.&lt;/p&gt;

&lt;h2&gt;
  
  
  What can we actually verify offline?
&lt;/h2&gt;

&lt;p&gt;Consider an issuer signing a mandate that identifies a principal, an agent, permitted actions, and transaction constraints.&lt;/p&gt;

&lt;p&gt;A local verifier can check the issuer's signature against an explicitly trusted public key. It can then evaluate a specific transaction against the verified mandate.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Agent:&lt;/strong&gt; &lt;code&gt;agent:treasury-bot&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Action:&lt;/strong&gt; &lt;code&gt;transfer&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Per-transaction limit:&lt;/strong&gt; USD 100.00&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Requested amount:&lt;/strong&gt; USD 50.00&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the signature is valid and the request satisfies the static constraints, the system can conclude that the request is &lt;em&gt;eligible for an authoritative authorization check&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;It cannot conclude that the payment should be executed.&lt;/p&gt;

&lt;p&gt;There are at least three reasons.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Revocation:&lt;/strong&gt; An issuer can revoke a delegation after signing it. The old signature remains cryptographically valid.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cumulative budgets:&lt;/strong&gt; An agent may have spent its total allowance across earlier requests. A local per-transaction check cannot establish the remaining distributed balance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Replay:&lt;/strong&gt; A request can be validly signed and still be submitted more than once.&lt;/p&gt;

&lt;p&gt;These are mutable facts that require an authoritative source of current state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Encoding that boundary in Rust
&lt;/h2&gt;

&lt;p&gt;This distinction is central to &lt;a href="https://github.com/fintechbear/fintechbear-kya-suite" rel="noopener noreferrer"&gt;FintechBear KYA&lt;/a&gt;, an open-source Rust SDK for AI-agent delegated authority verification and transaction policy evaluation.&lt;/p&gt;

&lt;p&gt;The SDK separates a local policy result from a final authorization decision.&lt;/p&gt;

&lt;p&gt;A successful local evaluation produces a &lt;code&gt;PolicyOutcome&lt;/code&gt;. It does not produce an automatic &lt;code&gt;Allow&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There is deliberately no &lt;code&gt;From&amp;lt;PolicyOutcome&amp;gt; for Decision&lt;/code&gt; conversion.&lt;/p&gt;

&lt;p&gt;Instead, the application must go through the &lt;code&gt;authorize&lt;/code&gt; bridge and supply an &lt;code&gt;OnlineAuthorizer&lt;/code&gt; that can make the authoritative decision.&lt;/p&gt;

&lt;p&gt;The trade-off is deliberate: the SDK cannot independently authorize a payment. Applications need to implement the online authority.&lt;/p&gt;

&lt;p&gt;That is a better failure mode than silently treating an offline check as permission.&lt;/p&gt;

&lt;h2&gt;
  
  
  A runnable example
&lt;/h2&gt;

&lt;p&gt;The repository contains a Rust demo that exercises this distinction.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/fintechbear/fintechbear-kya-suite.git
&lt;span class="nb"&gt;cd &lt;/span&gt;fintechbear-kya-suite
cargo run &lt;span class="nt"&gt;-p&lt;/span&gt; kya-examples &lt;span class="nt"&gt;--example&lt;/span&gt; demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The example:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Configures an explicitly trusted issuer public key.&lt;/li&gt;
&lt;li&gt;Creates and verifies a genuinely signed Ed25519 mandate using a test-only signing key.&lt;/li&gt;
&lt;li&gt;Evaluates the USD 50.00 transaction against the USD 100.00 limit.&lt;/li&gt;
&lt;li&gt;Rejects a mandate whose signature has been modified.&lt;/li&gt;
&lt;li&gt;Denies a USD 100.01 request that exceeds the signed limit.&lt;/li&gt;
&lt;li&gt;Sends an eligible policy outcome to an example online authorizer that cannot establish approval.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The demo reports an eligible static outcome, but that result is not authorization.&lt;/p&gt;

&lt;p&gt;Its failure cases include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[4] in-scope transaction is ELIGIBLE (requires_online_authorization=true).

[5a] tampered signature rejected fail-closed:
     signature did not verify (VerificationSignatureInvalid).

[5b] over-limit intent denied by stage C:
     reason=AmountExceedsLimit (terminal, fail-closed).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The online-authority part of the demonstration also shows that an unresolved approval requirement or an unavailable authority does not become an &lt;code&gt;Allow&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;These are illustrative test transactions, not real payment executions.&lt;/p&gt;

&lt;p&gt;You can inspect the &lt;a href="https://github.com/fintechbear/fintechbear-kya-suite/blob/main/examples/demo.rs" rel="noopener noreferrer"&gt;full demo source&lt;/a&gt; and &lt;a href="https://github.com/fintechbear/fintechbear-kya-suite/blob/main/docs/demo.md" rel="noopener noreferrer"&gt;captured output&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why exact money matters
&lt;/h2&gt;

&lt;p&gt;Authorization constraints should not depend on floating-point rounding.&lt;/p&gt;

&lt;p&gt;FintechBear KYA uses integer minor units with explicit currency information.&lt;/p&gt;

&lt;p&gt;For USD, &lt;code&gt;10_000&lt;/code&gt; minor units represent $100.00. The example's $100.01 request exceeds that limit by exactly one cent.&lt;/p&gt;

&lt;p&gt;That makes the boundary explicit and testable.&lt;/p&gt;

&lt;p&gt;It does not solve cumulative spending enforcement. Per-transaction limits and distributed budgets are different problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the SDK does not implement
&lt;/h2&gt;

&lt;p&gt;This is an early &lt;code&gt;v0.1.0&lt;/code&gt; pre-release.&lt;/p&gt;

&lt;p&gt;The open-source core provides local evidence verification, deterministic static policy evaluation, and interfaces for the later authorization and execution stages.&lt;/p&gt;

&lt;p&gt;It does not currently ship:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Agent proof-of-possession verification.&lt;/li&gt;
&lt;li&gt;A concrete online revocation service.&lt;/li&gt;
&lt;li&gt;Distributed cumulative-budget enforcement.&lt;/li&gt;
&lt;li&gt;Global replay protection.&lt;/li&gt;
&lt;li&gt;Payment execution enforcement.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Its AP2-style adapter is experimental; confirmed AP2 wire interoperability is not claimed.&lt;/p&gt;

&lt;p&gt;The project has not undergone an independent third-party security audit and is not presented as a production-ready payment authorization system.&lt;/p&gt;

&lt;p&gt;These boundaries are documented in the &lt;a href="https://github.com/fintechbear/fintechbear-kya-suite/blob/main/docs/security-limitations.md" rel="noopener noreferrer"&gt;security limitations&lt;/a&gt; and &lt;a href="https://github.com/fintechbear/fintechbear-kya-suite/blob/main/docs/threat-model.md" rel="noopener noreferrer"&gt;threat model&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The engineering question
&lt;/h2&gt;

&lt;p&gt;For a financial action initiated by an AI agent, signature verification and static policy are necessary parts of a possible design.&lt;/p&gt;

&lt;p&gt;But where should the boundary between &lt;em&gt;verified evidence&lt;/em&gt; and &lt;em&gt;current authorization&lt;/em&gt; live?&lt;/p&gt;

&lt;p&gt;FintechBear KYA puts that boundary explicitly in the API: local eligibility cannot be silently promoted to an authorization decision.&lt;/p&gt;

&lt;p&gt;I'd be interested in how other Rust and security engineers approach this separation, particularly when the authoritative service is unavailable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Source:&lt;/strong&gt; &lt;a href="https://github.com/fintechbear/fintechbear-kya-suite" rel="noopener noreferrer"&gt;https://github.com/fintechbear/fintechbear-kya-suite&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disclosure:&lt;/strong&gt; This article was drafted with AI assistance.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>security</category>
      <category>opensource</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
