<?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: João André Gomes Marques</title>
    <description>The latest articles on DEV Community by João André Gomes Marques (@jagmarques).</description>
    <link>https://dev.to/jagmarques</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%2F3836862%2Fad35883e-4652-4a30-9d8f-555f5048648b.png</url>
      <title>DEV Community: João André Gomes Marques</title>
      <link>https://dev.to/jagmarques</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jagmarques"/>
    <language>en</language>
    <item>
      <title>Self-attested vs independently verifiable receipts</title>
      <dc:creator>João André Gomes Marques</dc:creator>
      <pubDate>Sun, 02 Aug 2026 10:00:00 +0000</pubDate>
      <link>https://dev.to/jagmarques/self-attested-vs-independently-verifiable-receipts-29bc</link>
      <guid>https://dev.to/jagmarques/self-attested-vs-independently-verifiable-receipts-29bc</guid>
      <description>&lt;p&gt;A receipt is only as credible as the party that vouches for it. The two kinds of receipt differ in one place: who signs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The distinction
&lt;/h2&gt;

&lt;p&gt;A self-attested receipt is signed by the same platform that ran the agent. The platform vouches for its own agent, so you are trusting that platform's word about itself. There is no independent party in the loop, which makes the receipt an assertion rather than third-party evidence.&lt;/p&gt;

&lt;p&gt;An independently verifiable receipt is signed and anchored by a party other than the one that ran the agent. Any counterparty can verify it without trusting the issuing platform. The check runs on your own machine, with no account at the issuer and no call back to it, so the receipt holds up even if the platform that issued it disappears.&lt;/p&gt;

&lt;h2&gt;
  
  
  Side by side
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                        Self-attested
                        Independently verifiable

                        Who vouches
                        The platform that ran the agent
                        An unaffiliated party, separate from the one that ran the agent

                        Can a counterparty verify it
                        Only by trusting the issuing platform's word
                        Yes, on their own machine, with no account and no call to the issuer

                        Tamper evidence
                        The issuer can rewrite its own record
                        Each receipt links to its predecessor in a hash chain and anchors to external witnesses, so edits are detectable

                        Audit trail
                        Held by the issuing platform
                        Anchored and packed into a portable bundle a reviewer can take away
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The difference is structural, not a matter of trust in a brand. A self-attested receipt asks a counterparty to take the agent platform at its word. An independently verifiable receipt lets the counterparty check the claim themselves.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Asqav does it
&lt;/h2&gt;

&lt;p&gt;Asqav is the unaffiliated party in the loop. It signs as an operator independent of the agent's operator, so the receipt does not rest on the agent platform's word. The pipeline maps to five primitives.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Sign. The action is signed server-side with an ML-DSA key (NIST FIPS 204) held under Asqav custody. The agent's operator never holds the signing key, so the recorded party cannot forge or backdate its own record.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Attest. The receipt records the action context and the authorization behind it, so the signed claim is reproducible offline from the payload.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Anchor. Each receipt joins the agent's hash chain and anchors through OpenTimestamps onto Bitcoin, so the tamper evidence does not depend on Asqav's clock or storage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verify. Anyone holding the receipt resolves the public verify key and checks the signature themselves, with no Asqav account and no call to Asqav.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Audit-pack. Receipts export into a compliance bundle, with PDF export for the EU AI Act deployer audit pack, portable to a reviewer.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Walk the whole flow in the quickstart, or scaffold a project and validate your setup with asqav quickstart. For the offline procedure, see independent verification.&lt;/p&gt;




&lt;p&gt;Asqav provides cryptographic governance for AI agents through signed, tamper-evident receipts covering actions, policy decisions, result digests, and independent timestamps. Receipts support recordkeeping and independent verification; they do not by themselves establish legal compliance, which depends on the system and jurisdiction. Founded by João Marques.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The OWASP AI Exchange cites the Asqav compliance-receipts profile</title>
      <dc:creator>João André Gomes Marques</dc:creator>
      <pubDate>Tue, 28 Jul 2026 10:00:00 +0000</pubDate>
      <link>https://dev.to/jagmarques/the-owasp-ai-exchange-cites-the-asqav-compliance-receipts-profile-4bdl</link>
      <guid>https://dev.to/jagmarques/the-owasp-ai-exchange-cites-the-asqav-compliance-receipts-profile-4bdl</guid>
      <description>&lt;p&gt;The OWASP AI Exchange now cites the Asqav compliance-receipts profile. The Exchange's page on input threats, in the section on monitoring and secure logging, describes a signed-receipt approach to tamper-evident logging and links draft-marques-asqav-compliance-receipts as one open profile that sets out receipt-format obligations under the EU AI Act, DORA, and US sector regulations.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the citation says
&lt;/h2&gt;

&lt;p&gt;The secure-logging guidance recommends tamper-evident logging to verify that records stay unmodified after an incident. It describes a signed-receipt approach that binds a hash of the input, the output, and the processing context to a per-event signature, paired with an independent time anchor so the signer cannot backdate the "when". It then names the compliance-receipts profile as an open definition of those receipt-format obligations. The citation sits on the page at owaspai.org/docs/2_threats_through_use.&lt;/p&gt;

&lt;p&gt;The Exchange also sets out why tamper-evident logging is harder for AI than for conventional applications. Output is non-deterministic, so a signature over the response alone proves little. Retention runs to multiple years under the EU AI Act and DORA. And for agents it matters who acted under whose authority, and which model and tools were available when the action was signed. Those are the properties the receipt format is built around.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who runs the AI Exchange
&lt;/h2&gt;

&lt;p&gt;The OWASP AI Exchange is an OWASP Flagship project. Its founder and lead editor is Rob van der Veer, Chief AI Officer at Software Improvement Group, who also works on ISO/IEC 27090 and the EU AI Act standard in CEN/CENELEC. Through an official liaison partnership, the Exchange feeds its content into ISO/IEC 27090, the international standard for AI security. Rob van der Veer personally thanked the founder for the contribution that led to the citation.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it means
&lt;/h2&gt;

&lt;p&gt;The citation is independent recognition of the signed-receipt approach to AI-agent accountability. The Exchange describes the same shape Asqav ships: a signature that binds what went in and what came out to the processing context, anchored so the signer cannot rewrite history. Asqav signs each record server-side with keys held by an operator unaffiliated with the agent's operator, which supports the recordkeeping obligations the Exchange lists.&lt;/p&gt;

&lt;p&gt;The recognition also reaches the verification protocol. An authoritative Asqav receipt is reproducible: the server re-derives the subject it signs, and any third party can re-derive the same record and check the ML-DSA-65 signature against the public keys Asqav publishes, with no callback to Asqav. A reviewer does not have to take Asqav's word for it, which is the property a tamper-evident log needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Read it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The citing page: OWASP AI Exchange, input threats, secure logging.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The profile: draft-marques-asqav-compliance-receipts on the IETF Datatracker.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Asqav provides cryptographic governance for AI agents through signed, tamper-evident receipts covering actions, policy decisions, result digests, and independent timestamps. Receipts support recordkeeping and independent verification; they do not by themselves establish legal compliance, which depends on the system and jurisdiction. Founded by João Marques.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Out-of-process signing for high-assurance agent audit trails</title>
      <dc:creator>João André Gomes Marques</dc:creator>
      <pubDate>Mon, 20 Jul 2026 12:00:00 +0000</pubDate>
      <link>https://dev.to/jagmarques/out-of-process-signing-for-high-assurance-agent-audit-trails-1bcm</link>
      <guid>https://dev.to/jagmarques/out-of-process-signing-for-high-assurance-agent-audit-trails-1bcm</guid>
      <description>&lt;p&gt;An AI agent that signs its own audit trail holds the signing key in its own process memory. That arrangement is convenient, and it has a hole in it. An attacker who compromises the agent, through a prompt injection that reaches code execution, a poisoned tool dependency, or a memory-safety bug in a model runtime, gets arbitrary code execution inside the agent. With in-process signing, that attacker can read the signing key out of memory, mint forged receipts that look indistinguishable from genuine ones, and backdate or alter the hash chain to hide what they did.&lt;/p&gt;

&lt;p&gt;Out-of-process signing closes that hole by moving the signer into a separate trust boundary. The agent keeps an API key and nothing else. The signing key lives in a process the agent cannot read, ideally in a customer-controlled KMS or HSM the agent operator never touches. A compromised agent can still request signatures, but it cannot extract the key, and the signer's own audit log records every request.&lt;/p&gt;

&lt;h2&gt;
  
  
  The threat the boundary closes
&lt;/h2&gt;

&lt;p&gt;Name the adversary before the feature. An attacker with process-level access to an in-process-signing agent has three moves available.&lt;/p&gt;

&lt;p&gt;Read the signing key out of process memory. Once the key is exfiltrated, the attacker signs anything they like, anywhere, with no further help from the agent.&lt;/p&gt;

&lt;p&gt;Mint forged receipts that look genuine. With the key, the attacker produces signatures the verifier accepts. The audit trail now contains records of actions the agent never performed.&lt;/p&gt;

&lt;p&gt;Backdate or alter the hash chain. Remove a receipt that incriminates the attacker, recompute the chain, and a stored-versus-stored check passes if the verifier trusts stored columns.&lt;/p&gt;

&lt;p&gt;Out-of-process signing removes the first move, which removes the second, because without the key the attacker cannot forge. The third move is handled separately, by the rule that verification re-derives every hash from the canonical bytes instead of comparing two stored values.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a compromised agent can still do
&lt;/h2&gt;

&lt;p&gt;A precise threat model names the residual, not only the win. The agent holds an API key. An attacker holding that API key can request signatures on content they chose. That residual holds for any signer that sits outside the agent, whatever its shape: a signature proves who recorded what and when, not that the reporting process told the truth.&lt;/p&gt;

&lt;p&gt;Asqav narrows the residual instead of hiding it. Each receipt can declare its capture path, so a verifier can tell a self-reported receipt from one captured by a network proxy or an eBPF probe at a boundary the agent does not control. Output binding through result_digest, counterparty acknowledgments, and a WebAuthn user co-signature each tie a receipt to evidence the agent cannot produce alone.&lt;/p&gt;

&lt;p&gt;The other residual is silence. A receipt that was never requested leaves no trace by itself. Deployments that capture at a boundary record traffic the agent never reported, which gives an auditor a second record set to compare the signed receipts against.&lt;/p&gt;

&lt;h2&gt;
  
  
  The architecture
&lt;/h2&gt;

&lt;p&gt;The signer ships as a single container image. Both deployment shapes, Asqav-hosted SaaS and customer-deployed self-hosted, use the same image and emit the same wire format.&lt;/p&gt;

&lt;p&gt;The agent process imports the Asqav SDK and talks to the signer over a Unix domain socket or mTLS. The signer holds the ML-DSA-65 keys, validates each request, signs, and appends to the hash chain. The signer talks to Asqav SaaS over a single outbound HTTPS hop to deposit signed digests and RFC 3161 timestamps. Raw prompts, raw model outputs, and private keys never leave the customer trust boundary in the self-hosted shape.&lt;/p&gt;

&lt;p&gt;The Python SDK reaches the signer through one environment variable. Point it at &lt;a href="https://api.asqav.com/api/v1" rel="noopener noreferrer"&gt;https://api.asqav.com/api/v1&lt;/a&gt; and you use the Asqav-hosted notary signer. Point it at a local socket or a private signer URL and you use a customer-deployed signer. The SDK call is identical in both cases. The trust boundary changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the boundary has regulatory weight
&lt;/h2&gt;

&lt;p&gt;Regulators and assessors expect the key custody question to have a clean answer.&lt;/p&gt;

&lt;p&gt;SEC 17a-4(f) gives broker-dealers two ways to execute the required electronic-records undertakings: a designated third party unaffiliated with the broker-dealer, or an internal designated executive officer. Asqav fits the unaffiliated-third-party route, which co-located keys inside the audited workload cannot. NYDFS 23 NYCRR 500.06 calls for audit trail systems sufficient to reconstruct material financial transactions. DORA Articles 28 to 30 have financial entities evidence ICT third-party risk management. HIPAA covered entities that handle PHI in the workload have to show an assessor who controls the signing keys.&lt;/p&gt;

&lt;p&gt;In each case the architectural question is the same. Does the signing key live inside the workload that uses it, or in a separate trust boundary? The out-of-process signer is the answer assessors expect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who deploys this topology
&lt;/h2&gt;

&lt;p&gt;Customers in regulated industries typically deploy the customer-hosted signer. A US broker-dealer that needs SEC 17a-4(f)(3)(v) unaffiliated-third-party evidence. A covered entity under HIPAA where the agent processes PHI inside the workload. A DORA-regulated EU financial entity where Article 28 ICT third-party-risk concentration on a hosted signer is itself an audit finding. A defense contractor where the agent runs inside a CMMC enclave and the signer must run inside the same enclave.&lt;/p&gt;

&lt;p&gt;Teams iterating on a new AI feature, or self-serve teams without a hard regulatory boundary, typically use the Asqav-hosted notary signer until they need the customer-deployed topology.&lt;/p&gt;

&lt;p&gt;The operational detail for the self-hosted shape, including the air-gapped install with zero outbound HTTP, is on the out-of-process signing page.&lt;/p&gt;




&lt;p&gt;Asqav provides cryptographic governance for AI agents through signed, tamper-evident receipts covering actions, policy decisions, result digests, and independent timestamps. Receipts support recordkeeping and independent verification; they do not by themselves establish legal compliance, which depends on the system and jurisdiction. Founded by João Marques.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Signed receipts for AI coding agents</title>
      <dc:creator>João André Gomes Marques</dc:creator>
      <pubDate>Mon, 20 Jul 2026 10:00:00 +0000</pubDate>
      <link>https://dev.to/jagmarques/signed-receipts-for-ai-coding-agents-2fjn</link>
      <guid>https://dev.to/jagmarques/signed-receipts-for-ai-coding-agents-2fjn</guid>
      <description>&lt;p&gt;AI coding agents now open their own pull requests and merge them. The git author string on a commit is mutable, so a name in a commit header proves nothing about who wrote the change or under whose authority. When an auditor asks which agent wrote which change, git history alone cannot answer.&lt;/p&gt;

&lt;p&gt;The code-authorship receipt is our answer. It is a signed, hash-chained, anchored record that a specific code change existed, was authored by the holder of a signing key, and held a fixed position in the per-agent chain at time T. The authoritative form ships under receipt type authoritative, minted by POST /code-authorship.&lt;/p&gt;

&lt;h2&gt;
  
  
  The server re-derives the diff
&lt;/h2&gt;

&lt;p&gt;The receipt does not trust a digest the producer hands over. Asqav re-fetches the commit from the GitHub API, re-derives the changed-files diff itself, and signs the SHA-256 it computed over the canonical form of that diff. The signed subject digest is the server value only. A client-supplied change_digest is advisory: it is compared against the server digest and the agreement is recorded as digest_match, but the client value is never signed. A producer that posts a fake digest still receives a receipt whose subject is the value the server computed from GitHub, with the mismatch flagged in the predicate.&lt;/p&gt;

&lt;p&gt;Because the server signs a digest it re-derives from a public commit, the receipt is reproducible. Any third party who re-fetches the same commit_sha from GitHub repeats the same projection and recomputes the same digest, then checks it against the signed subject. The producer cannot move the signed subject, because the producer never controls the bytes that feed it. That is what makes the receipt unbypassable.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the receipt proves, and what it does not
&lt;/h2&gt;

&lt;p&gt;A code-authorship receipt proves a bounded set of facts and refuses to claim anything beyond them.&lt;/p&gt;

&lt;p&gt;The change existed, and the server verified it. The subject.digest.sha256 is the SHA-256 the server re-derived from the GitHub compare response and signed. It is a digest the producer cannot forge, because the producer never supplies it.&lt;/p&gt;

&lt;p&gt;The change was key-authored. The signature is an ML-DSA-65 signature from a key held outside the agent's environment. Whoever holds that key produced, or authorized, the change. The public key is served for offline verification at /.well-known/jwks.json.&lt;/p&gt;

&lt;p&gt;The change held a fixed position in the chain. Each receipt links to the one before it. Reorder, delete, or insert a backdated receipt and the chain breaks at the exact spot.&lt;/p&gt;

&lt;p&gt;The capture layer is server-derived too. The receipt stamps capture_layer: github_sha_pull, and any capture_topology a client supplies is dropped before signing, so a caller cannot spoof how the change was captured. In-process capture is observation-only across Asqav: a self-reported in-process receipt cannot drive an allow or deny decision, and the conformance gate fails closed on the attempt.&lt;/p&gt;

&lt;p&gt;What the receipt does not prove is just as important. Asqav does not verify the code is correct or safe, and it does not verify which model produced the change. The author field is advisory, carried in the predicate for correlation and never read as Asqav-verified attribution. The receipt is a record, not a code review.&lt;/p&gt;

&lt;h2&gt;
  
  
  A code-authorship receipt on the wire
&lt;/h2&gt;

&lt;p&gt;The receipt is an in-toto Statement v1 wrapped in a DSSE envelope. The subject names the commit and carries the server-re-derived digest. The predicate carries the producer assertions and the capture layer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://in-toto.io/Statement/v1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"subject"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"github.com/acme/payments-service@9f3c1d8b4a6e2f0c5d7b9a1e3c4f6d8b0a2e4c6f"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"digest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"sha256"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"c4d9f1a7e0b3..."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"predicateType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://asqav.com/attestation/code-authorship/v1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"predicate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"repo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"acme/payments-service"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"commit_sha"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"9f3c1d8b4a6e2f0c5d7b9a1e3c4f6d8b0a2e4c6f"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"base_sha"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"capture_layer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"github_sha_pull"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"asset_class"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"change_class"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"write"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"advisory_client_digest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sha256:c4d9f1a7e0b3..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"digest_match"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"author"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"agt_release_bot"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"verified_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-07-28T14:11:02.000000Z"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The signed bytes are the DSSE Pre-Authentication Encoding of the payload type and the canonical statement, so a verifier recomputes that encoding from the decoded payload and checks the ML-DSA-65 signature offline, with no callback to any Asqav server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it plugs in
&lt;/h2&gt;

&lt;p&gt;The receipt rides the same supply-chain attestation tooling teams already run. It maps onto an in-toto Statement v1, with the subject array naming the produced digest and the predicate carrying the producer assertions and the chain position. Wrapped that way, it rides the same transparency-log rails as a Sigstore Rekor entry or a GitHub Artifact Attestations submission.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it maps to in an audit
&lt;/h2&gt;

&lt;p&gt;A code-authorship receipt is evidence, not a compliance guarantee. It maps to change-management and record-keeping obligations without claiming to satisfy them on its own.&lt;/p&gt;

&lt;p&gt;SOC 2 change management asks for evidence that changes are authorized and tracked. A signed, chained, anchored receipt proves which change was authored at time T, in a form an auditor can verify offline. FINRA and SEC records rules require records that are tamper-evident and independently verifiable. EU AI Act Article 12 requires automatic recording of events over an AI system's lifetime, and a code change authored by an agent in the software development lifecycle is one such event.&lt;/p&gt;

&lt;p&gt;In every case Asqav supplies the evidence layer. The receipt proves the change happened and held its place in the chain. Whether the change was correct, the model attribution accurate, or the approval sufficient stays the deploying organization's judgment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sign one
&lt;/h2&gt;

&lt;p&gt;Call POST /code-authorship with repo and commit_sha. The server resolves the diff base as the merge-base of the associated pull request, or the git empty tree for a parentless initial commit. A commit that has parents but no pull request is refused with 422 (base_sha_required) rather than guessing a first parent. It then re-fetches the changed files from GitHub and signs the re-derived digest. Private repositories need a configured GitHub token, and without one a private-repo re-fetch fails closed rather than signing a fallback. The Asqav GitHub Action mints one receipt per merged PR when wired into the CI path.&lt;/p&gt;

&lt;p&gt;Read more on the code-authorship receipts page.&lt;/p&gt;




&lt;p&gt;Asqav provides cryptographic governance for AI agents through signed, tamper-evident receipts covering actions, policy decisions, result digests, and independent timestamps. Receipts support recordkeeping and independent verification; they do not by themselves establish legal compliance, which depends on the system and jurisdiction. Founded by João Marques.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How Signed Agent Receipts Map to NIST, OWASP, and NSA Frameworks</title>
      <dc:creator>João André Gomes Marques</dc:creator>
      <pubDate>Mon, 06 Jul 2026 12:00:00 +0000</pubDate>
      <link>https://dev.to/jagmarques/how-signed-agent-receipts-map-to-nist-owasp-and-nsa-frameworks-3fia</link>
      <guid>https://dev.to/jagmarques/how-signed-agent-receipts-map-to-nist-owasp-and-nsa-frameworks-3fia</guid>
      <description>&lt;p&gt;A signed agent receipt answers one question well: did this agent perform this action, under this policy, at this time. An auditor or a buyer usually asks a second question right after. Which control does that map to. Which line of NIST, which OWASP risk, which article of the regulation.&lt;/p&gt;

&lt;p&gt;Most tooling answers the second question in a separate place. The action log lives in one system and the control-coverage spreadsheet lives in another, and an auditor has to trust that the two line up. Asqav puts the mapping inside the signed receipt, so the answer to both questions travels in one tamper-evident record. This post walks through how that works across four bodies of guidance, and it links the reference pages that carry the full field-by-field detail.&lt;/p&gt;

&lt;h2&gt;
  
  
  The mapping direction, stated plainly
&lt;/h2&gt;

&lt;p&gt;One thing to fix before the tables. A receipt field provides verifiable evidence of an activity that a control objective asks you to record. It supports that objective. It does not certify that your organization has met every clause of a publication. Asqav records evidence in a form an auditor can verify; the auditor still makes the judgment. Keeping that line clear is what makes the mapping honest rather than a compliance badge.&lt;/p&gt;

&lt;h2&gt;
  
  
  The taxonomy fields a receipt can carry
&lt;/h2&gt;

&lt;p&gt;Asqav binds caller-supplied control mappings into the signed receipt through seven optional wire fields plus one server-set guard. The seven fields reference the frameworks a compliance pipeline already uses.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                        Field
                        What it carries

                    mitre_techniquesMITRE ATT&amp;amp;CK technique ids
                    mitre_atlasMITRE ATLAS ids for AI-system threats
                    owasp_llm_top10OWASP Top 10 for LLM ids
                    nist_ai_rmfNIST AI RMF function ids and subcategories
                    iso_42001ISO/IEC 42001 control ids
                    eu_ai_act_articlesEU AI Act article ids
                    rfc3161_timestampBase64 TimeStampResp for offline TSA verification
                    framework_mappings_self_declaredServer-set guard, described below
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;All seven caller-supplied fields are optional. None is mandatory on any receipt type. A decision receipt with taxonomy binding looks like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"action_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"api:call"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"receipt_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"protectmcp:decision"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"policy_decision"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"permit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mitre_techniques"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"T1059"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"T1078"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"owasp_llm_top10"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"LLM01"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"LLM02"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"nist_ai_rmf"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"GOVERN-1.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MEASURE-2.7"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"eu_ai_act_articles"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Article-12"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Article-15"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"framework_mappings_self_declared"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The signed envelope binds every one of these fields. A verifier who recovers the receipt later cannot change any value without breaking the ML-DSA signature. The full field list, the sign-time validation rules, and the SDK snippets are on the threat-framework mapping page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Self-declared, and marked as such
&lt;/h2&gt;

&lt;p&gt;This is the part that keeps the mapping trustworthy. Asqav does not validate that an owasp_llm_top10 value is a real OWASP id, or that a nist_ai_rmf subcategory exists in the published framework. The values are caller-supplied and preserved verbatim. The producer asserts what the action maps to; Asqav signs the bytes.&lt;/p&gt;

&lt;p&gt;To stop a false attestation, the framework_mappings_self_declared guard is set by the server. It flips to true whenever any taxonomy list is populated, even if the caller passes false. A verifier reading the receipt sees the self-declared label plainly, so no one mistakes a producer's own classification for something Asqav checked. It is the same asymmetry Asqav uses elsewhere: the signed label, not the content it points to, is what the receipt attests.&lt;/p&gt;

&lt;h2&gt;
  
  
  NIST SP 800-53: the AU control family
&lt;/h2&gt;

&lt;p&gt;The AU family in NIST SP 800-53 Rev. 5 covers audit and accountability. It maps onto receipt content closely, because a receipt is an audit record. AU-3, the content of audit records, asks that a record establish six things. Each one lands on a receipt field.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                        AU-3 element
                        Receipt field

                    What type of eventaction_type, receipt_type
                    When it occurredissued_at, anchors
                    Where it occurredcapture_topology, tool_fingerprint
                    Source of the eventagent_id, authorized_under_mandate
                    Outcomecontrols_evaluated.result, result_digest
                    Identity of the subjectagent_id, authored_by
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Two AU controls are worth calling out. AU-9 asks you to protect audit information from unauthorized modification. Each receipt is signed with ML-DSA-65 by an operator key held outside the agent's environment, so a field changed after signing produces a verifiable signature failure, and the previousReceiptHash chain makes a deletion detectable. AU-10 covers non-repudiation, and it is the control a signed receipt serves most directly. Because the signing key is held by a party unaffiliated with the agent operator, neither the operator nor the agent can deny that a sign call was made without forging a post-quantum signature.&lt;/p&gt;

&lt;p&gt;AU-12 addresses record generation, and it is where the controls_evaluated block earns its place. That block is built by the server and dropped if a caller tries to supply it, so it cannot be forged. It records which enforcement controls actually ran on a sign call, such as policy, mandate, quorum, and content scan. An absent key means the control did not run. That makes the audit mechanism itself auditable, which is a nice property to be able to show a reviewer.&lt;/p&gt;

&lt;h2&gt;
  
  
  NIST AI Risk Management Framework
&lt;/h2&gt;

&lt;p&gt;The NIST AI RMF organizes work into Govern, Map, Measure, and Manage. Its auditability subcategory under Govern asks whether you established mechanisms that make the AI system's processes traceable. The controls_evaluated map traces the governance process, result_digest binds each outcome, policy_digest lets an auditor confirm which policy version was in effect, and risk_class carries the deployer's risk rating into the signed record. Populate the nist_ai_rmf list and the self-declared guard flips, so the mapping is marked producer-declared right there in the receipt.&lt;/p&gt;

&lt;h2&gt;
  
  
  OWASP: LLM and agentic risks
&lt;/h2&gt;

&lt;p&gt;The OWASP Top 10 for LLM Applications 2025 and the OWASP Top 10 for Agentic Applications 2026 describe application and agent risks that produce clear evidence needs.&lt;/p&gt;

&lt;p&gt;Excessive Agency, LLM06 in the 2025 list, has the most direct field-level mapping. A receipt records which authority checks ran through controls_evaluated, what mandate the action was signed under through authorized_under_mandate, and how the deployer classified the action through risk_class. On the 2026 agentic list, several categories line up cleanly. Agent Goal Hijack and the previousReceiptHash chain let a responder reconstruct the sequence leading up to a detected drift. Identity and Privilege Abuse maps to the distinct agent_id and the mandate binding. Insecure Inter-Agent Communication maps to a bilateral receipt with a counterparty binding. Rogue Agents maps to the three independent signals of controls_evaluated, authorized_under_mandate, and risk_class together. The full mapping, category by category, is on the NIST and OWASP receipt mapping page.&lt;/p&gt;

&lt;h2&gt;
  
  
  NSA guidance on MCP security
&lt;/h2&gt;

&lt;p&gt;In May 2026 the NSA published a Cybersecurity Information Sheet on Model Context Protocol security (U/OO/6030316-26). It sets out recommendations spanning several product categories. Asqav covers the receipt and audit layer of that guidance and is candid about the parts it does not cover.&lt;/p&gt;

&lt;p&gt;On signing and verifying MCP messages, Asqav records a server-issued timestamp, a per-receipt nonce that keys the consumer's own duplicate check, and an expiry on each receipt, signs the envelope with ML-DSA-65, and publishes the verify key at a well-known endpoint. On logging and detection, receipt columns capture the action type, the request digest, the tool fingerprint, and a hash of the result, which is the cryptographic-hash-of-output leg the guidance calls for. The honest half matters just as much: Asqav is not a filtering outgoing proxy, not a data-loss-prevention tool, and not an in-line interception proxy, and four recommendations in the sheet belong to a different product class entirely. The NSA MCP guidance coverage page lays out which recommendations are direct, which are partial, and which are out of scope.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the mapping belongs in the receipt
&lt;/h2&gt;

&lt;p&gt;A standalone governance tool keeps a control-coverage spreadsheet next to the action log. An auditor then reconciles two systems and hopes they agree. When the mapping rides inside the signed receipt, there is one canonical chain to check, and the cryptographic binding guarantees the receipt was issued against that mapping, not a later one that papered over a missed control.&lt;/p&gt;

&lt;p&gt;None of this makes Asqav a conformance validator. It does not score your AI RMF maturity or decide whether you met AU-9. It records, in a signed and tamper-evident receipt, the evidence a compliance team needs to make those calls, in a form the reviewer can verify without trusting Asqav. The guidance frames what evidence is needed. The receipt is the mechanism that preserves it.&lt;/p&gt;

&lt;p&gt;Start with the three reference pages: the NIST and OWASP receipt mapping, the threat-framework mapping, and the NSA MCP guidance coverage. Or create a free account and bind a taxonomy-tagged receipt today.&lt;/p&gt;




&lt;p&gt;Asqav provides cryptographic governance for AI agents through signed, tamper-evident receipts covering actions, policy decisions, result digests, and independent timestamps. Receipts support recordkeeping and independent verification; they do not by themselves establish legal compliance, which depends on the system and jurisdiction. Founded by João Marques.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Tamper-Evident Logs for AI Agents</title>
      <dc:creator>João André Gomes Marques</dc:creator>
      <pubDate>Mon, 06 Jul 2026 10:00:00 +0000</pubDate>
      <link>https://dev.to/jagmarques/tamper-evident-logs-for-ai-agents-3jgl</link>
      <guid>https://dev.to/jagmarques/tamper-evident-logs-for-ai-agents-3jgl</guid>
      <description>&lt;p&gt;A tamper-evident log is not a log you promise not to edit. It is a record where an edit shows. That distinction is the whole game. Access controls try to stop the edit. Tamper evidence assumes the edit happens anyway and makes it visible after the fact, to someone who does not trust your storage.&lt;/p&gt;

&lt;p&gt;We argued the case for this in an earlier post on why AI agent logs are not enough. That post covered the gap: a plain log records a claim, it does not prove one. This post is about the machinery that closes the gap. How a signed agent record is built, and what actually happens to it when someone tries to change it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What tampering looks like
&lt;/h2&gt;

&lt;p&gt;Start with the adversary, not the feature. Suppose an AI agent moved money, deleted a record, or approved something it should not have. Someone now wants the audit trail to say otherwise. They have four moves.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Edit a field. Change the amount, the destination, the timestamp, or the policy decision on a stored record.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete a record. Remove the row that shows the action happened at all.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reorder records. Shuffle the sequence so a later action looks like it came earlier.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Backdate. Insert a record and claim it was written hours or days before it really was.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each move needs its own defense. A signature catches the edit. A hash chain catches the delete and the reorder. An external anchor catches the backdate. Below is how each one works on an Asqav receipt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Signed receipts: catching the edit
&lt;/h2&gt;

&lt;p&gt;Every agent action produces a receipt. Before the action runs, Asqav serializes it, evaluates it against policy, and signs the result with a private key. The signature covers the exact bytes of the record. Change a single field later and the signature no longer matches those bytes. Anyone holding the public key sees the failure.&lt;/p&gt;

&lt;p&gt;The signature algorithm is ML-DSA-65, Level 3 and widely recommended for most applications, defined in NIST FIPS 204, the module-lattice signature standard NIST published in 2024. It is post-quantum, which matters because agent audit trails carry long retention windows and a signature written today needs to stand up years from now. The point for tamper evidence is simpler though: the signed bytes are fixed at signing time, and no edit to them goes unnoticed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the bytes have to be canonical
&lt;/h2&gt;

&lt;p&gt;There is a subtlety here. The same record can be written many ways. Keys in a different order, extra whitespace, a number formatted two ways. If the signer and the verifier disagree on which bytes to hash, verification breaks on records that were never touched, and that is useless.&lt;/p&gt;

&lt;p&gt;Asqav fixes the byte layout with a canonical form, the JSON Canonicalization Scheme from RFC 8785. Object keys are sorted, strings are preserved verbatim, and floating-point ambiguity is kept out of signed envelopes. One record, one byte sequence, one hash. The signature and every downstream hash are computed over that canonical form, so the same content always lands on the same digest.&lt;/p&gt;

&lt;h2&gt;
  
  
  The per-agent hash chain: catching the delete and the reorder
&lt;/h2&gt;

&lt;p&gt;A signature protects one record. It does nothing about a record that was removed, because a deleted record takes its signature with it. That is what the hash chain handles.&lt;/p&gt;

&lt;p&gt;Each agent has its own chain. Every receipt carries a previousReceiptHash field: the SHA-256 of the prior receipt's canonical bytes. The opening receipt on a chain seeds this field with 64 zeros, a genesis marker that means "no predecessor". From there, each receipt's hash becomes the next receipt's previousReceiptHash, so the records are linked in a single line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"receipt_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"protectmcp:decision"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"action_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"payments:transfer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"agent_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"agt_trading_bot_01"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"issued_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-07-06T10:30:00Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"previousReceiptHash"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"9f2c...prior receipt canonical SHA-256..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"policy_decision"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"permit"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the delete costs the attacker. Remove one receipt and the next one's previousReceiptHash points at a hash that nothing produces anymore. The link dangles. Reorder two receipts and the same thing happens: the chain expects one predecessor and finds another. A verifier walking the chain sees the break at the exact record where it happened.&lt;/p&gt;

&lt;p&gt;Asqav also tells apart a real break from an expected one. When a previous_hash points to a record owned by a different agent, the verifier labels it cross_agent rather than tampering, so an operator reading a report knows which links are structure and which are damage.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rule that makes it hold: re-derive, never trust the stored hash
&lt;/h2&gt;

&lt;p&gt;Here is the mechanic that ties the rest together, and it is the one people miss. A naive integrity check compares two stored values: the hash column on this row against the hash column on the next. An attacker who can edit a field can also edit that column. Rewrite the record, recompute its hash, write the new hash into the column, and a stored-versus-stored check passes.&lt;/p&gt;

&lt;p&gt;Asqav does not do that. Every verifier re-derives the hash from the canonical bytes of the record and compares the fresh result against what the chain expects. The stored hash column is never trusted as the source of truth. So editing a field and rewriting its hash does not help: the re-derived hash reflects the edit, and it no longer matches the value the next record committed to. The same holds for the anchor commitment, which is always recomputed from the receipt message rather than read back from a stored column. Tampering that would slip past a stored comparison surfaces here.&lt;/p&gt;

&lt;p&gt;This is the difference between a log that claims to be immutable and a record that proves it. The proof does not depend on the database behaving. It depends on math the verifier runs itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  External anchors: catching the backdate
&lt;/h2&gt;

&lt;p&gt;Signatures and chains keep the record internally consistent. They do not, on their own, prove when a record was written. An attacker who controls the whole store could rebuild a fresh, internally consistent chain and claim it is old. That is where an outside witness comes in.&lt;/p&gt;

&lt;p&gt;Asqav anchors each receipt to a public timeline at the moment it is issued. Two anchor types are supported: an OpenTimestamps proof committed to the Bitcoin blockchain, and an external timestamp from an RFC 3161 time-stamping authority. Both commit to the receipt's bytes, and both are re-verified against those bytes at check time, not taken on faith that a log entry exists somewhere.&lt;/p&gt;

&lt;p&gt;A backdated record cannot produce an anchor that predates it, because the public timeline it would need to appear in had already moved on. The anchor is the part of the proof that no single party, including Asqav, can quietly rewind.&lt;/p&gt;

&lt;h2&gt;
  
  
  Transparency logs: a third party that remembers
&lt;/h2&gt;

&lt;p&gt;Anchors prove time. A transparency log adds an independent record that a receipt existed and was seen. Asqav can export a receipt as a COSE_Sign1 structure signed by the same ML-DSA-65 key, in a form a transparency service built on the IETF SCITT work can ingest. We covered that export path in detail in the post on ML-DSA receipts in COSE for SCITT transparency services.&lt;/p&gt;

&lt;p&gt;The value for tamper evidence is the second witness. Your own store says the receipt exists. A transparency service, run by someone else, says it saw the same receipt. To make a tampered record look real, an attacker would now have to alter both, and the second one is not theirs to touch.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the evidence proves, and what it does not
&lt;/h2&gt;

&lt;p&gt;Tamper evidence is worth having because it is honest about its own limits. A cryptographically valid receipt tells you who signed what, and that the bytes have not changed since. It does not tell you the action was safe, correct, or wise. It does not tell you nothing bypassed the signer.&lt;/p&gt;

&lt;p&gt;Asqav makes that boundary explicit. A receipt can be paired with a signed appraisal that reports what verification actually confirmed, grouped by axis: authorship, provenance, transparency, and policy. The appraisal carries a fixed list of things it does not assert, including action safety, complete mediation, and key non-compromise. There is no single trusted or valid flag, because a valid signature is not a verdict on the decision it records. An audit stands on evidence that knows what it is, not on a green checkmark.&lt;/p&gt;

&lt;h2&gt;
  
  
  Putting it together
&lt;/h2&gt;

&lt;p&gt;Tamper evidence for an agent record is four mechanisms doing four jobs. The signature over canonical bytes catches the edit. The per-agent hash chain catches the delete and the reorder. The external anchor catches the backdate. The transparency log adds a witness that is not you. And the rule underneath all of it is that verification re-derives every hash from the bytes instead of trusting a stored value, so the proof holds even when the storage does not.&lt;/p&gt;

&lt;p&gt;If you want the field-level detail, the documentation walks through the receipt format, and the logs are not enough post covers why plain logging leaves that gap open to begin with. Or create a free account and sign an agent action today.&lt;/p&gt;




&lt;p&gt;Asqav provides cryptographic governance for AI agents through signed, tamper-evident receipts covering actions, policy decisions, result digests, and independent timestamps. Receipts support recordkeeping and independent verification; they do not by themselves establish legal compliance, which depends on the system and jurisdiction. Founded by João Marques.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>SDK 0.6.0: offline and air-gapped verification</title>
      <dc:creator>João André Gomes Marques</dc:creator>
      <pubDate>Sat, 20 Jun 2026 10:00:00 +0000</pubDate>
      <link>https://dev.to/jagmarques/sdk-060-offline-and-air-gapped-verification-1k3</link>
      <guid>https://dev.to/jagmarques/sdk-060-offline-and-air-gapped-verification-1k3</guid>
      <description>&lt;p&gt;SDK 0.6.0 ships today for both Python (asqav) and TypeScript (@asqav/sdk). The main addition is a clean offline verification path for environments that cannot reach the internet during an audit run.&lt;/p&gt;

&lt;p&gt;The idea is simple: fetch the public key directory once while you are connected, then everything else is local. No special mode, no API key, no Asqav infrastructure involved during the verify step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Offline verification in one pass
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# snapshot the public key directory once&lt;/span&gt;
curl https://api.asqav.com/.well-known/jwks.json &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; jwks.json

&lt;span class="c"&gt;# install the verify dependencies&lt;/span&gt;
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="s2"&gt;"asqav[verify]"&lt;/span&gt;

&lt;span class="c"&gt;# verify with no network access&lt;/span&gt;
python verify_receipt.py &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--receipt&lt;/span&gt; receipt.json &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--jwks&lt;/span&gt; jwks.json &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--offline&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The --offline flag makes the verifier refuse to make any network call. If a key is missing from your local snapshot, the issuer-key axis fails rather than fetching silently.&lt;/p&gt;

&lt;h2&gt;
  
  
  ML-DSA-65 works the same way
&lt;/h2&gt;

&lt;p&gt;Post-quantum receipts (ML-DSA-65, NIST FIPS 204) verify offline the same way as Ed25519 receipts. The algorithm identifier rides inside the signed envelope, so the verifier reads which algorithm to use from the receipt itself. The pure-Python dilithium-py library handles the signature math with no native compilation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Air-gapped installs
&lt;/h2&gt;

&lt;p&gt;If the target machine has no internet at all, pre-download the wheels on a connected machine and transfer them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip download &lt;span class="s2"&gt;"asqav[verify]"&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; ./wheels
&lt;span class="c"&gt;# transfer ./wheels/ to the air-gapped machine&lt;/span&gt;
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--no-index&lt;/span&gt; &lt;span class="nt"&gt;--find-links&lt;/span&gt; ./wheels &lt;span class="s2"&gt;"asqav[verify]"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;Full offline verification guide: asqav.com/docs/offline-air-gapped-verification. Source: github.com/jagmarques/asqav-sdk.&lt;/p&gt;




&lt;p&gt;Asqav provides cryptographic governance for AI agents through signed, tamper-evident receipts covering actions, policy decisions, result digests, and independent timestamps. Receipts support recordkeeping and independent verification; they do not by themselves establish legal compliance, which depends on the system and jurisdiction. Founded by João Marques.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>One Receipt, Nine Regulators</title>
      <dc:creator>João André Gomes Marques</dc:creator>
      <pubDate>Sat, 09 May 2026 22:50:17 +0000</pubDate>
      <link>https://dev.to/jagmarques/one-receipt-nine-regulators-gbk</link>
      <guid>https://dev.to/jagmarques/one-receipt-nine-regulators-gbk</guid>
      <description>&lt;p&gt;We published an IETF Internet-Draft, draft-marques-asqav-compliance-receipts-08, that profiles the upstream draft-farley-acta-signed-receipts envelope with regulatory bindings. This post explains what the profile does, why each piece is there, and how the authoritative attestation and verification protocol fits in.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the profile does
&lt;/h2&gt;

&lt;p&gt;The upstream draft specifies a generic signed receipt envelope for AI agent actions: a wire format, a canonicalization rule, a signature suite, and an optional hash chain. It is intentionally regulation-agnostic. The Asqav profile takes that envelope as-is and adds four things on top of it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It tightens fields that the upstream draft marks OPTIONAL into REQUIRED for any receipt that claims the profile, including payload_digest, action_ref, and policy_digest.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It sets a retention floor tied to the underlying regulation: 184 days (six months) for high-risk AI Act receipts, five years for DORA receipts under the sectoral instruments (MiFID II Art 16(7), AMLD Art 40).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It mandates an anchor on every receipt. Every receipt carries an OpenTimestamps witness on all plans. Pro and Enterprise receipts also carry an RFC 3161 timestamp.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It adds two extension fields, risk_class and incident_class, drawn from controlled vocabularies that match the regulatory text.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A receipt that conforms to the Asqav profile is, by construction, a conformant upstream receipt. The signature validates with stock libraries. The chain validates with stock verifiers. A verifier that does not know about EU AI Act can still walk the receipt and confirm cryptographic facts. It just cannot attest the compliance bindings. Cryptographic validity and compliance attestation are different claims, and they fail independently.&lt;/p&gt;

&lt;h2&gt;
  
  
  A concrete binding
&lt;/h2&gt;

&lt;p&gt;Article 12(2)(c) of the EU AI Act requires operators of high-risk systems to monitor the operation of the system and detect substantial modifications. The profile binds Article 12(2)(c) to the policy_digest field. A change in policy_digest between two otherwise-comparable Actions, same issuer_id, same action_ref family, same risk_class, is treated as a candidate substantial-modification event. The verifier surfaces those candidates. A human decides whether the change was substantial in the regulatory sense. The receipt log is the evidence trail. The binding lives in the field-level conformance rule, not in a separate PDF.&lt;/p&gt;

&lt;p&gt;DORA Article 17 works the same way. The upstream draft says retention is out of scope. The profile sets a five-year floor for any receipt whose issuer_id is bound to a Financial Entity scope, sourced from the sectoral instruments (MiFID II Art 16(7), AMLD Art 40), and ties that floor to the OpenTimestamps anchor so deletion before the floor expires is detectable from the chain alone. If a receipt's anchor proves it existed five years ago and the producer cannot show it now, that is a finding. The supervisor does not have to take anyone's word for it.&lt;/p&gt;

&lt;p&gt;The draft now maps the receipt format onto nine regulatory regimes across the EU and US: EU AI Act, DORA, NYDFS Part 500, NIST AI RMF, Colorado AI Act, Texas TRAIGA, CIRCIA, the HIPAA Security Rule, and SEC 17a-4. The pattern is the same in every case: pick the regulatory obligation, identify the receipt field that already carries the relevant fact, write a conformance rule that a verifier can mechanically check.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authoritative attestation and verification
&lt;/h2&gt;

&lt;p&gt;The draft registers code-authorship extensions and a verifier-behaviour protocol, and Asqav ships both. The authoritative attestation path, POST /code-authorship, re-fetches a commit from GitHub, re-derives the changed-files diff server-side, and signs the digest it computed. The signed subject is the server value, never a client-supplied one, so the producer cannot forge or backdate the record. The receipt carries the receipt type authoritative and the server-derived capture layer github_sha_pull.&lt;/p&gt;

&lt;p&gt;The verification protocol is issuer-free. A third party resolves the signing key at /.well-known/jwks.json, recomputes the DSSE Pre-Authentication Encoding over the in-toto statement, and checks the ML-DSA-65 signature with no callback to Asqav. The same verifier walks the per-agent hash chain and checks the anchor. Because the authoritative digest is re-derived from a public commit, any third party that re-fetches the commit_sha reproduces it and confirms the subject independently.&lt;/p&gt;

&lt;p&gt;Read the draft on the IETF Datatracker.&lt;/p&gt;




&lt;p&gt;Asqav provides cryptographic governance for AI agents through signed, tamper-evident receipts covering actions, policy decisions, result digests, and independent timestamps. Receipts support recordkeeping and independent verification; they do not by themselves establish legal compliance, which depends on the system and jurisdiction. Founded by João Marques.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>compliance</category>
      <category>opensource</category>
    </item>
    <item>
      <title>An IETF profile for AI agent compliance receipts</title>
      <dc:creator>João André Gomes Marques</dc:creator>
      <pubDate>Mon, 04 May 2026 11:58:11 +0000</pubDate>
      <link>https://dev.to/jagmarques/why-a-profile-not-a-fork-extending-the-ietf-signed-receipts-draft-for-eu-ai-act-2clg</link>
      <guid>https://dev.to/jagmarques/why-a-profile-not-a-fork-extending-the-ietf-signed-receipts-draft-for-eu-ai-act-2clg</guid>
      <description>&lt;p&gt;We published an IETF Internet-Draft, draft-marques-asqav-compliance-receipts-08, that profiles the upstream draft-farley-acta-signed-receipts envelope with regulatory bindings. This post explains what the profile does, why each piece is there, and how the authoritative attestation and verification protocol fits in.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the profile does
&lt;/h2&gt;

&lt;p&gt;The upstream draft specifies a generic signed receipt envelope for AI agent actions: a wire format, a canonicalization rule, a signature suite, and an optional hash chain. It is intentionally regulation-agnostic. The Asqav profile takes that envelope as-is and adds four things on top of it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It tightens fields that the upstream draft marks OPTIONAL into REQUIRED for any receipt that claims the profile, including payload_digest, action_ref, and policy_digest.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It sets a retention floor tied to the underlying regulation: 184 days (six months) for high-risk AI Act receipts, five years for DORA receipts under the sectoral instruments (MiFID II Art 16(7), AMLD Art 40).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It mandates an anchor on every receipt. Every receipt carries an OpenTimestamps witness on all plans. Pro and Enterprise receipts also carry an RFC 3161 timestamp.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It adds two extension fields, risk_class and incident_class, drawn from controlled vocabularies that match the regulatory text.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A receipt that conforms to the Asqav profile is, by construction, a conformant upstream receipt. The signature validates with stock libraries. The chain validates with stock verifiers. A verifier that does not know about EU AI Act can still walk the receipt and confirm cryptographic facts. It just cannot attest the compliance bindings. Cryptographic validity and compliance attestation are different claims, and they fail independently.&lt;/p&gt;

&lt;h2&gt;
  
  
  A concrete binding
&lt;/h2&gt;

&lt;p&gt;Article 12(2)(c) of the EU AI Act requires operators of high-risk systems to monitor the operation of the system and detect substantial modifications. The profile binds Article 12(2)(c) to the policy_digest field. A change in policy_digest between two otherwise-comparable Actions, same issuer_id, same action_ref family, same risk_class, is treated as a candidate substantial-modification event. The verifier surfaces those candidates. A human decides whether the change was substantial in the regulatory sense. The receipt log is the evidence trail. The binding lives in the field-level conformance rule, not in a separate PDF.&lt;/p&gt;

&lt;p&gt;DORA Article 17 works the same way. The upstream draft says retention is out of scope. The profile sets a five-year floor for any receipt whose issuer_id is bound to a Financial Entity scope, sourced from the sectoral instruments (MiFID II Art 16(7), AMLD Art 40), and ties that floor to the OpenTimestamps anchor so deletion before the floor expires is detectable from the chain alone. If a receipt's anchor proves it existed five years ago and the producer cannot show it now, that is a finding. The supervisor does not have to take anyone's word for it.&lt;/p&gt;

&lt;p&gt;The draft now maps the receipt format onto nine regulatory regimes across the EU and US: EU AI Act, DORA, NYDFS Part 500, NIST AI RMF, Colorado AI Act, Texas TRAIGA, CIRCIA, the HIPAA Security Rule, and SEC 17a-4. The pattern is the same in every case: pick the regulatory obligation, identify the receipt field that already carries the relevant fact, write a conformance rule that a verifier can mechanically check.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authoritative attestation and verification
&lt;/h2&gt;

&lt;p&gt;The draft registers code-authorship extensions and a verifier-behaviour protocol, and Asqav ships both. The authoritative attestation path, POST /code-authorship, re-fetches a commit from GitHub, re-derives the changed-files diff server-side, and signs the digest it computed. The signed subject is the server value, never a client-supplied one, so the producer cannot forge or backdate the record. The receipt carries the receipt type authoritative and the server-derived capture layer github_sha_pull.&lt;/p&gt;

&lt;p&gt;The verification protocol is issuer-free. A third party resolves the signing key at /.well-known/jwks.json, recomputes the DSSE Pre-Authentication Encoding over the in-toto statement, and checks the ML-DSA-65 signature with no callback to Asqav. The same verifier walks the per-agent hash chain and checks the anchor. Because the authoritative digest is re-derived from a public commit, any third party that re-fetches the commit_sha reproduces it and confirms the subject independently.&lt;/p&gt;

&lt;p&gt;Read the draft on the IETF Datatracker.&lt;/p&gt;




&lt;p&gt;Asqav provides cryptographic governance for AI agents through signed, tamper-evident receipts covering actions, policy decisions, result digests, and independent timestamps. Receipts support recordkeeping and independent verification; they do not by themselves establish legal compliance, which depends on the system and jurisdiction. Founded by João Marques.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>security</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Verify is not just true or false, granular outcomes on /verify</title>
      <dc:creator>João André Gomes Marques</dc:creator>
      <pubDate>Sun, 03 May 2026 18:16:42 +0000</pubDate>
      <link>https://dev.to/jagmarques/verify-is-not-just-true-or-false-granular-outcomes-on-verify-25dg</link>
      <guid>https://dev.to/jagmarques/verify-is-not-just-true-or-false-granular-outcomes-on-verify-25dg</guid>
      <description>&lt;p&gt;Until last week the public verify endpoint at &lt;code&gt;GET /api/v1/verify/{signature_id}&lt;/code&gt; returned a single boolean: &lt;code&gt;{verified: true}&lt;/code&gt; or &lt;code&gt;{verified: false}&lt;/code&gt;. That works for the buyer's first-glance UX. It does not work for a regulator or a court trying to figure out what actually went wrong.&lt;/p&gt;

&lt;p&gt;An older trust-data-infrastructure design we read for context lays this out: their verify can return Valid Document, Invalid Signature, Incorrect Hash, Invalid Receiver Public Key, or Valid Document (Adulteration Not Detected). Each label is a different forensic story. Invalid Receiver Public Key means substitution or man-in-the-middle. Incorrect Hash means transit corruption. Invalid Signature means key compromise.&lt;/p&gt;

&lt;p&gt;A boolean cannot carry that.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we added
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"verified"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"verification_detail"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"signer_key_match"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"signature_valid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"algorithm_match"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"agent_active"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"validation_label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"valid"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;---&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;Asqav&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;provides&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;cryptographic&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;governance&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;AI&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;agents&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;through&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;signed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;tamper-evident&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;receipts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;covering&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;policy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;decisions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;result&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;digests&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;independent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;timestamps.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Receipts&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;support&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;recordkeeping&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;independent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;verification;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;they&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;do&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;not&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;by&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;themselves&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;establish&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;legal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;compliance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;which&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;depends&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;system&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;jurisdiction.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Founded&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;by&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;João&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Marques.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Four sub-checks plus a stable label. The label resolves to one of: &lt;code&gt;valid&lt;/code&gt;, &lt;code&gt;invalid_signature&lt;/code&gt;, &lt;code&gt;signer_key_changed&lt;/code&gt;, &lt;code&gt;algorithm_mismatch&lt;/code&gt;, &lt;code&gt;agent_inactive&lt;/code&gt;, &lt;code&gt;agent_unknown&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The field is optional. Older clients that do not know about it ignore it. New clients render the per-axis breakdown. Backwards-compatible by construction.&lt;/p&gt;

&lt;p&gt;The public verify HTML at &lt;code&gt;asqav.com/verify/&amp;lt;signature_id&amp;gt;&lt;/code&gt; got a small grid below the existing fields, conditional on the API returning the detail.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this is for
&lt;/h2&gt;

&lt;p&gt;A regulator asks: when did this signature go bad? Was it the day the key was rotated? You want a label, not a bool.&lt;/p&gt;

&lt;p&gt;A court admissibility question: was this record signed by the agent the policy claims signed it, or by something with a different public key? You want &lt;code&gt;signer_key_match&lt;/code&gt; as its own line.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>security</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Every rejection leaves a trail, persistent log of rejected attempts</title>
      <dc:creator>João André Gomes Marques</dc:creator>
      <pubDate>Sun, 03 May 2026 18:11:20 +0000</pubDate>
      <link>https://dev.to/jagmarques/every-rejection-leaves-a-trail-persistent-log-of-rejected-attempts-516o</link>
      <guid>https://dev.to/jagmarques/every-rejection-leaves-a-trail-persistent-log-of-rejected-attempts-516o</guid>
      <description>&lt;p&gt;A rejection is data. Until recently we were throwing it away.&lt;/p&gt;

&lt;p&gt;If an attacker submitted a forged signature against the public verify endpoint, we returned &lt;code&gt;404 signature_not_found&lt;/code&gt; and that was the entire footprint. Same for a cross-org access attempt on the replay endpoint, an agent that got suspended mid-run trying to sign once more, or a probe walking through random &lt;code&gt;sig_*&lt;/code&gt; ids.&lt;/p&gt;

&lt;p&gt;An older trust-data-infrastructure project we read during a cold audit is explicit about this: log every invocation including the invalid ones, "para auditoria futura". It is the right call. We borrowed it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What landed
&lt;/h2&gt;

&lt;p&gt;One new table, &lt;code&gt;rejected_attempts&lt;/code&gt;. Indexed on &lt;code&gt;(organization_id, created_at)&lt;/code&gt; and &lt;code&gt;(agent_id, created_at)&lt;/code&gt; for fast org-scoped time-window scans.&lt;/p&gt;

&lt;p&gt;A logging helper that captures IP, User-Agent, and X-Request-ID, truncates user-supplied bytes, commits its own row, and swallows persistence failures so logging canno&lt;/p&gt;




&lt;p&gt;Asqav provides cryptographic governance for AI agents through signed, tamper-evident receipts covering actions, policy decisions, result digests, and independent timestamps. Receipts support recordkeeping and independent verification; they do not by themselves establish legal compliance, which depends on the system and jurisdiction. Founded by João Marques.t become a 5xx.&lt;/p&gt;

&lt;p&gt;Wired at the verify endpoint (signature and approval not-found branches), the signature lookup and replay endpoints (not-found and cross-org branches), and the sign and countersign paths.&lt;/p&gt;

&lt;h2&gt;
  
  
  How operators query it
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;GET /api/v1/observability/rejected-attempts&lt;/code&gt;, scoped to your organization, available on every plan including Free. Filters: &lt;code&gt;failure_reason&lt;/code&gt;, &lt;code&gt;agent_id&lt;/code&gt;, time window, pagination.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to do with the data
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Probe alerting. N rejections from one IP in M minutes is a probe.&lt;/li&gt;
&lt;li&gt;Suspended-agent retries. A revoked or decommissioned agent that keeps trying is misconfigured or compromised.&lt;/li&gt;
&lt;li&gt;Cross-org access attempts. A bearer token from one org hitting a signature_id from another org is the kind of thing you find out about months later. Now you find out the same hour.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>security</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Per-agent hash chain, with a verifier that re-derives</title>
      <dc:creator>João André Gomes Marques</dc:creator>
      <pubDate>Sun, 03 May 2026 18:05:22 +0000</pubDate>
      <link>https://dev.to/jagmarques/per-agent-hash-chain-with-a-verifier-that-re-derives-3g9b</link>
      <guid>https://dev.to/jagmarques/per-agent-hash-chain-with-a-verifier-that-re-derives-3g9b</guid>
      <description>&lt;p&gt;We hash-chain every signature record so a tamper or a delete is detectable on a later integrity check. The chain has been live for months. It worked. It also had two real problems we did not surface until we did a cold audit against an older trust-data-infrastructure (TDI) project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem 1: the chain was global
&lt;/h2&gt;

&lt;p&gt;Every new signature record took its previous-hash from the most recent record across the entire database. Not the most recent record for the same agent. Not the most recent record for the same organization. The most recent record, period.&lt;/p&gt;

&lt;p&gt;That makes a single global chain across every tenant. If tenant A's record is mutated or removed, the chain breaks at the next record from any tenant. A long-running customer with an active integration could have their chain show as broken because a different customer in a different country had a row deleted by a cleanup job.&lt;/p&gt;

&lt;p&gt;It also has a write hot spot. Two parallel signs across any two tenants both read the same chain head, both compute the same previous-hash, both insert. The integrity check then flags the second insert as broken even though no one tampered with anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problem 2: the verifier never re-derived
&lt;/h2&gt;

&lt;p&gt;The verifier walked records in order and checked that each row's previous-hash matched the prior row's stored hash. That catches a deleted row. It does not catch a row mutation that also rewrites its own stored hash.&lt;/p&gt;

&lt;p&gt;The fix is to re-derive the record hash from the canonical fields and compare. If the recomputed hash differs from the stored one, that row was mutated.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changed
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Chain heads are scoped per agent.&lt;/li&gt;
&lt;li&gt;The verifier re-derives every record hash instead of trusting the stored value.&lt;/li&gt;
&lt;li&gt;Records that predate the change keep their old cross-agent links; the verifier reports those under a separate legacy reason instead of calling them tampering.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you run a similar chain anywhere (audit log, ledger, payments), the two checks above are worth a 30-minute look. Global ordering and stored-hash comparison both feel safe and both have failure modes that quietly do not surface until someone audits them.&lt;/p&gt;

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