Model or dataset
jagmarques/asqav-sdk avatar
jagmarques/asqav-sdk

asqav-sdk: Signed Compliance Receipts for AI Agent Actions

Python and TypeScript SDKs for verifiable evidence of AI agent actions. Signed receipts, policy enforcement, audit trails. Works with LangChain, CrewAI, MCP.

591 stars40 forksPythonNOASSERTION

At a glance

What is it?
The asqav-sdk project ships Python and TypeScript clients that turn each agent action into a hash-chained, ML-DSA-65 signed receipt. Anyone can verify a receipt without an Asqav account, but signing requires the hosted service.
Who is it for?
Teams that need a portable, independently verifiable record of what an AI agent did should evaluate asqav-sdk, especially if they already run LangChain, CrewAI or MCP. Teams that cannot send action context to a hosted service, or that need the signing key to stay on their own infrastructure, should not adopt it: cryptography runs server-side, and the SDK is a client.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 12 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The gap asqav-sdk fills: proving what an agent actually did

Application logs tell you what your own code chose to write down. They do not survive an adversarial reading. A log line can be edited, backfilled or deleted, and nothing in the file proves which process produced it. When an agent calls a model, moves money or touches a customer record, the question an auditor asks is narrower and harder: can you show me this specific action happened, in this order, and can I check that claim myself without taking your word for it.

asqav-sdk answers that question with a signed receipt per action. The README describes the receipt as ML-DSA-65 (FIPS 204, post-quantum), timestamped against independent witnesses, and verifiable by anyone, including a regulator, without an Asqav account. The audience is therefore teams under audit pressure: EU AI Act readiness, DORA reporting, internal AI governance programmes. The topics list names those frameworks directly, along with LangChain, CrewAI, MCP and OpenAI Agents as the runtimes it plugs into.

The design decision that shapes everything else is stated plainly in the README: zero native dependencies in either SDK, because cryptography runs server-side. That keeps installation trivial and pushes the trust boundary onto the hosted service.

How a receipt is built: sign locally, hash-chain, verify cold

The SDK surface is small. You call govern() with an API key and an agent name, and it returns an agent object. Calling sign() on that agent with an action type and a context object produces a signature whose verification_url is the artefact you hand to someone else.

The chain is the interesting part. The README states that verify() recomputes chain_hash locally as the SHA-256 over the RFC 8785 canonical payload, so the chain link is reproducible on your machine. RFC 8785 is JSON Canonicalization Scheme: key ordering and number formatting are normalised before hashing, which means two implementations that serialise the same logical object differently still agree on the digest. Without that step, a Python dict and a JavaScript object would hash differently and the chain would be unverifiable across languages.

The repository layout reinforces the point. conformance/ holds shared fixtures that both SDKs run against, and CI reruns both matrices whenever conformance/ changes even if neither language directory was touched. The README says the TypeScript verifier is held to verdict parity with the Python oracle by that same corpus. For a two-language SDK, that is the right place to spend engineering effort: cross-language drift in a verification path is the failure that destroys trust in the whole scheme.

Verification comes in two strengths. The account-free verify() returns the public verdict and the recomputed chain hash. A stronger path exists for zero-trust checks: asqav.verify_receipt_offline(receipt, jwks) in Python, verifyReceiptOffline() in TypeScript, or the standalone python -m asqav.verifier.verify_receipt --offline. The algorithm is taken per-receipt from signature.alg, ML-DSA-65 for cloud-issued receipts and Ed25519 or ES256 for locally signed ones. That per-receipt algorithm field is a sensible choice: it lets the format outlive one signature scheme.

Installing the SDK and signing a first action

Both packages install from their public registries. The README gives the two commands and the supported runtimes: Python 3.10 or later, and Node 20.19 through 20.x, or 22.12 and later. Note the Node range: 21.x is not listed, so check your runtime before pinning.

bash
pip install asqav            # Python 3.10+
npm install @asqav/sdk       # Node 20.19 through 20.x, or 22.12 and later

Signing an action in Python needs an API key. The README example passes it directly, but reading it from the environment is the same call with a different argument.

python
import asqav

agent = asqav.govern(api_key="sk_...", agent_name="my-agent")
sig = agent.sign("api:openai:chat", {"model": "gpt-4o"})
print(sig.verification_url)

The TypeScript equivalent is asynchronous: govern() returns a promise, and sign() takes a single object with actionType and context rather than positional arguments.

ts
import { govern } from "@asqav/sdk";

const agent = await govern({ apiKey: process.env.ASQAV_API_KEY, agentName: "my-agent" });
const sig = await agent.sign({ actionType: "api:openai:chat", context: { model: "gpt-4o" } });
console.log(sig.verificationUrl);

To check a receipt without an account, call verify() with a signature id. The README uses a deliberately broken example id and states that it returns verified: false, because its signature bytes are placeholders and its kid resolves to no key. That is worth running once: a verifier that fails closed on absent evidence is the behaviour you want to confirm before you rely on it.

python
import asqav

result = asqav.verify("sig_example_regulator_cold_verify_2026")
print(result["verified"])     # False -- deliberately, see below
print(result["chain_hash"])

Finally, asqav doctor validates configuration and connectivity in any environment with ASQAV_API_KEY set, and returns non-zero on failure. The README points to docs/github-actions.md for a copy-paste workflow, which makes doctor the natural gate in CI.

What the receipt does not prove, and where the SDK is the wrong tool

The strongest thing in this README is a negative: the per-language guides are said to document what a receipt does not prove. Take that seriously, because the failure mode here is over-reading the evidence. A signature attests that a payload existed at a time and was not altered afterwards. It does not attest that the action described actually occurred, that the agent's output was correct, or that the context you passed in was complete. If your application signs a context object that omits the fields an auditor cares about, the receipt will be a perfectly valid proof of an incomplete record.

The second limitation is architectural. Cryptography runs server-side, so signing requires connectivity to asqav.com and an API key. An air-gapped deployment, a regulated environment that forbids sending action context to a third party, or a team that must hold its own signing keys cannot use the cloud signing path as described. The README does mention locally signed receipts with Ed25519 or ES256 algorithms, which suggests a local signing mode exists, but the top-level README does not document how to produce one; that detail is deferred to the per-language guides.

Third, the SDK is a client. There is no self-hosted server in the repository layout: python/, typescript/, conformance/, verifier/ and tooling, but no service to run yourself. The verifier is the only piece that runs entirely on your side, and it verifies rather than signs.

Finally, the licence is Elastic License 2.0, which is source-available rather than an OSI-approved open source licence. The repository metadata reports the licence as NOASSERTION, so read LICENSE directly before you plan around it.

Compared with signing agent actions yourself

The obvious alternative is to generate a keypair, sign a canonical JSON payload of each action, and append it to your own append-only store. That is a weekend of work and it removes the third party entirely. What you do not get is the part that is expensive to build: independent timestamping, a published verification endpoint that a counterparty can hit without credentials, a defined receipt format profiled in an IETF Internet-Draft, and a neutral verifier that a regulator can run. If your auditor is your own security team, build it yourself. If your auditor is external, the format and the witness are the product.

The second alternative is general-purpose signing and transparency tooling, such as Sigstore-style keyless signing or a plain RFC 3161 timestamp authority. Those solve provenance for build artefacts and documents. They do not know what an agent action is, they do not carry framework integrations for LangChain, CrewAI or MCP, and they do not ship a policy and audit layer. The difference is domain modelling: asqav-sdk is opinionated about the unit being signed, which is the agent action plus its context, and about the chain that links consecutive actions.

A third comparison is the observability stack you probably already run. Tracing tools record spans and attributes and are excellent for debugging. They are not designed to be tamper-evident or to be handed to a counterparty as evidence. The two are complementary: trace for diagnosis, receipt for proof.

Maintenance, release cadence and upgrade cost

The last push to the default branch was on 2026-09-09, eleven days before this writing, and the repository is not archived. Recent releases tell a more specific story: v0.6.0 on 2026-06-20, and Python py-v0.5.16 and TypeScript npm-v0.5.16 both on 2026-06-17. The two SDKs are versioned and released independently, and the README states that releases are driven by prefixed tags, py-v* publishing to PyPI via OIDC and ts-v* publishing to npm via an NPM_TOKEN secret.

Two consequences follow. First, the Python and TypeScript packages will not always carry the same version number, so a polyglot team should pin both explicitly rather than assume parity. Second, the 0.x versioning means the API is not yet frozen. This is pre-1.0 software; budget for occasional breaking changes on upgrade.

The conformance corpus is the main brake on upgrade cost. Because adding a feature means adding a fixture first and then making both SDKs pass it, and because CI reruns both matrices when conformance/ changes, a change that would silently diverge the two languages should be caught at PR time. That does not protect you from API changes, only from semantic drift between the implementations.

On licence: Elastic License 2.0 is not an OSI-approved open source licence, and the repository metadata reports NOASSERTION rather than naming it. If your organisation has a policy against source-available licences, or if you intend to offer the software as a hosted service, read LICENSE and get your own advice. Nothing here is legal advice; the point is simply that the licence is a decision input, not a formality.

Editorial conclusion

Teams that need a portable, independently verifiable record of what an AI agent did should evaluate asqav-sdk, especially if they already run LangChain, CrewAI or MCP. Teams that cannot send action context to a hosted service, or that need the signing key to stay on their own infrastructure, should not adopt it: cryptography runs server-side, and the SDK is a client. Before committing, verify three things: that the Free plan covers your volume, that your auditor accepts a receipt whose signing key lives at asqav.com, and that an offline verification run against your own JWKS returns verified: true.

Frequently asked questions

Does asqav-sdk work with LangChain, CrewAI and MCP?

The repository topics list LangChain, CrewAI, MCP and OpenAI Agents, and the README points to the per-language package READMEs for framework integrations. The top-level README does not show integration code, so check python/README.md or typescript/README.md for the specific hooks.

Can I verify an asqav receipt without an Asqav account?

Yes. The README states that anyone holding a signature_id can verify it without an API key, and verify() returns the public verdict while recomputing chain_hash locally. For a fully offline check that reproduces the signature itself, use asqav.verify_receipt_offline(receipt, jwks) in Python or verifyReceiptOffline() in TypeScript.

Does signing an action send data to asqav.com?

Signing requires an API key and, per the README, cryptography runs server-side, so the signing path depends on the hosted service. The README notes that locally signed receipts use Ed25519 or ES256, but the top-level README does not document how to produce one; the per-language guides are the reference.

What licence does asqav-sdk use?

The README states Elastic License 2.0, and the repository metadata reports the licence as NOASSERTION. That is source-available rather than an OSI-approved open source licence, so read LICENSE before adopting it.

Official sources

  1. Issues
  2. jagmarques/asqav-sdk on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/jagmarques-asqav-sdk.svg)](https://hysenlabs.com/projects/jagmarques-asqav-sdk)