Governance for AI agents. Audit trails, policy enforcement, and compliance.
Website | Docs | SDK Guide | Compliance
The official client SDKs for Asqav, the governance layer for AI agents. Sign every action with ML-DSA-65 (FIPS 204), enforce policies before execution, and produce regulator-ready audit trails.
This repository ships two SDKs from a single monorepo:
python/- the original Python SDK, published to PyPI asasqavtypescript/- the TypeScript SDK, published to npm as@asqav/sdk
Both wrap the same Asqav API. Pick the one that matches your stack.
Python:
pip install asqavTypeScript / Node.js:
npm install @asqav/sdkBoth packages have zero native dependencies. All ML-DSA cryptography runs server-side.
Python:
import asqav
asqav.init(api_key="sk_...")
agent = asqav.Agent.create("my-agent")
sig = agent.sign("api:call", {"model": "gpt-4"})
print(sig.signature_id, sig.verify_url)TypeScript:
import { Asqav } from "@asqav/sdk";
const asqav = new Asqav({ apiKey: "sk_..." });
const agent = await asqav.Agent.create("my-agent");
const sig = await agent.sign("api:call", { model: "gpt-4" });
console.log(sig.signatureId, sig.verifyUrl);Each signed action returns a receipt like:
{
"signature_id": "sig_a1b2c3",
"agent_id": "agt_x7y8z9",
"action": "api:call",
"algorithm": "ML-DSA-65",
"timestamp": "2026-04-27T18:30:00Z",
"chain_hash": "b94d27b9934d3e08...",
"verify_url": "https://asqav.com/verify/sig_a1b2c3"
}The agent now has a cryptographic identity, a signed audit trail, and a verifiable action record.
The SDK auto-detects whether you're pointing at the Asqav cloud or a self-hosted deployment, and selects the safer default for each:
- Cloud (
*.asqav.com): hash-only by default. The SDK builds a fingerprint of your action context, computes a SHA-256 hash locally, and sends only the hash plus a small metadata bag (action_type, agent_id, session_id, model_name, tool_name). Raw prompts and tool arguments stay on your side. - Self-hosted: full-payload by default. The server can run policy checks, PII redaction, and richer audit. Recommended when you control the deployment.
Override anytime:
# Python
asqav.init(api_key="...", base_url="https://api.asqav.com", mode="hash-only")// TypeScript
await init({ apiKey: "...", baseUrl: "https://api.asqav.com", mode: "hash-only" });The fingerprint format is RFC 8785-style sorted JSON with no whitespace, hashed with SHA-256. See docs/fingerprint-spec.md and conformance/vectors.json for the spec and cross-language test vectors.
What ships on Asqav today. Each item is available on main.
1. Hash-only mode for cloud
- WHAT: Hash-only mode on cloud. The SDK hashes
{action_type, context}locally with RFC 8785 + SHA-256 and sends only the hash plus a small whitelisted metadata bag. - WHY NOW: Default for any client pointed at api.asqav.com. Raw prompts and tool arguments never leave your process. Spec is open in
docs/fingerprint-spec.mdand cross-language vectors ship inconformance/vectors.json.
2. Self-hosted signer (split-trust)
- WHAT: Self-hosted signer container. Run the Asqav signing path inside your VPC; ML-DSA-65 private keys, raw prompts, and reasoning traces never cross the container boundary.
- WHY NOW: Compose file and env contract documented in the Asqav backend repo at
docker-compose.signer.ymlanddocs/self-hosted-signer.md. Optional digest-only relay back toapi.asqav.comis gated by a fixed allowlist enforced in code.
3. Bring-your-own KMS (AWS KMS / GCP KMS) - Enterprise tier
- WHAT: Bring-your-own KMS. Provision your agents' ML-DSA-65 keys in your own AWS KMS or GCP KMS so signing material lives in your HSM, not ours.
- WHY NOW: AWS KMS uses the
ML_DSA_65key spec on FIPS 140-3 Level 3 HSMs; GCP KMS usesPQ_SIGN_ML_DSA_65(currently in software preview, HSM coming). Toggle withKMS_PROVIDER=aws|gcp.
4. Customer-owned storage
- WHAT: Customer-owned storage on self-hosted. Postgres, Redis, raw payloads, and ML-DSA private keys all sit in your container. Optional upstream relay only ever sees
{hash, signature, timestamp, algorithm, agent_id, signature_id}. - WHY NOW: The allowlist is enforced in code at
src/asqav_cloud/core/signer_relay.py(Asqav backend repo) and asserted bytests/test_self_hosted_signer.py. Auditors can read the forbidden-keys frozenset and confirm what cannot leak.
5. SCITT / COSE_Sign1 receipt export
- WHAT: SCITT-compatible receipt export. Public
GET /api/v1/signatures/{id}/cosereturnsapplication/cose(CBOR tag 18). The same ML-DSA-65 key signs both the JCS form and the COSE_Sign1 form, so SCITT transparency services can ingest receipts directly. - WHY NOW: Receipt format and canonical record are deterministic. The CBOR encoder and registration policy are live; both forms share the same key material so existing JCS verifiers keep working unchanged.
6. Air-gapped / on-prem mode
- WHAT: Self-hosted signer with offline license validation and zero outbound HTTP.
- WHY NOW: Egress gate, license issuer, and operator guide live in the Asqav backend repo (
src/asqav_cloud/core/airgap.py,tools/issue_license.py,docs/airgapped-mode.md). Targeted at regulated EU institutions with no-egress requirements.
See the docs at https://asqav.com/docs for the current feature set.
Asqav's compliance receipts are profiled in IETF Internet-Draft draft-marques-asqav-compliance-receipts, an Independent Submission that profiles draft-farley-acta-signed-receipts for EU AI Act Articles 12 and 26, and DORA Article 17 bindings.
| Without governance | With Asqav |
|---|---|
| No record of what agents did | Every action signed with ML-DSA (FIPS 204) |
| Any agent can do anything | Policies block dangerous actions in real-time |
| One person approves everything | Multi-party authorization for critical actions |
| Manual compliance reports | Automated EU AI Act and DORA reports |
| Reasoning lost after the run | Prompt, trace, and output signed and replayable |
The root README only covers the cross-language story. For language-specific guides - decorators, async clients, framework integrations, CLI commands, local mode, batched signing, three-phase signing, scope tokens, replay, attestations, and more - see:
- Python:
python/README.md - TypeScript:
typescript/README.md
The full reference lives at asqav.com/docs.
Both SDKs cover the same core surface: agent identity, signed actions, batched signing, policy enforcement, scope tokens, replay, attestations, three-phase signing, and the user_intent envelope on agent.sign(...) (Ed25519 / ECDSA P-256 / WebAuthn).
The Python SDK additionally ships:
- The
asqavCLI:quickstart,demo,verify,doctor,agents,sync, plusreplay,preflight,approve,budget(check/record), andcompliance(frameworks/export). See asqav.com/docs/cli. - A pytest plugin (
pytest --asqav) that signs every test result and emits a Merkle-rooted compliance bundle on session finish. See asqav.com/docs/pytest-plugin. - Native callbacks for LangChain, CrewAI, LiteLLM, Haystack, OpenAI Agents SDK, LlamaIndex, smolagents, DSPy, PydanticAI, Letta, Strands, and Instructor (via the Hooks API).
- Cookbooks for Streamlit dashboards and Dify workflows under
python/examples/. - Local-mode offline signing with deferred sync.
The TypeScript SDK currently focuses on the core API and Agent surface for Node 20+ runtimes. It additionally ships:
- The
user_intentenvelope onagent.sign(...). - A Vercel AI SDK adapter at
@asqav/sdk/extras/vercel-aithat plugs intoexperimental_telemetry: { tracer }and signs every span the AI SDK opens.
Other framework integrations are tracked on the roadmap.
If a feature exists in one SDK but not the other, the language README will mark it explicitly.
asqav-sdk/
python/ Python SDK (pip install asqav)
src/
tests/
pyproject.toml
README.md
typescript/ TypeScript SDK (npm install @asqav/sdk)
src/
tests/
package.json
README.md
conformance/ Cross-language conformance fixtures both SDKs run against
.github/workflows/
ci.yml Path-filtered CI for both languages
publish.yml Tag-based publish (py-v* to PyPI, ts-v* to npm)
CHANGELOG.md
README.md (this file)
The two SDKs are versioned and released independently.
Receipts are portable. Anyone with a signature_id can verify it without an API key:
Python:
import asqav
result = asqav.verify("sig_a1b2c3")
assert result["verified"]
print(result["agent_id"], result["chain_hash"])TypeScript:
import { verify } from "@asqav/sdk";
const result = await verify("sig_a1b2c3");
console.assert(result.verified);
console.log(result.agentId, result.chainHash);Or open the receipt's verify_url in a browser. Hashes are reproducible offline from the RFC 8785 (the JSON format spec) payload, so auditors do not need to trust Asqav's servers - the signature speaks for itself.
The conformance/ directory contains shared test fixtures both SDKs run against. Adding a new feature means adding a fixture there first, then making both SDKs pass it. CI reruns both matrices whenever conformance/ changes, even if neither python/ nor typescript/ was touched, so cross-language drift is caught at PR time.
CI runs on every push to main and every pull request. It uses dorny/paths-filter@v3 to only execute the matrix jobs for the language whose source actually changed:
- Changes under
python/run pytest on Python 3.10, 3.11, and 3.12. - Changes under
typescript/run npm test on Node 20 and 22. - Changes under
conformance/or to the workflow itself run both.
A final aggregator job named ci-ok is the single required status check for branch protection. It passes when each matrix job either succeeded or was skipped (no relevant changes), which avoids the GitHub gotcha where a skipped required check stays pending forever.
asqav doctor validates configuration and connectivity in any environment with ASQAV_API_KEY set, returning non-zero on failure so it gates PRs cleanly. Pair it with asqav.compliance.export_bundle to package signed receipts from your test runs into a self-contained, Merkle-rooted artifact for auditors. See docs/github-actions.md for a copy-paste workflow.
See CONTRIBUTING.md for the full contributor guide. The short version:
- Fork the repo and create a feature branch.
- Run the relevant test suite locally.
- Python:
cd python && pip install -e ".[all]" pytest && pytest tests -v - TypeScript:
cd typescript && npm ci && npm test
- Python:
- Open a pull request against
main. CI must go green before merge.
Direct pushes to main are blocked. Every change lands through a PR.
Because both SDKs live in one repo but ship to different registries on independent cadences, releases are driven by prefixed git tags:
| Language | Tag pattern | Registry |
|---|---|---|
| Python | py-v0.2.21, py-v0.3.0, ... |
PyPI |
| TypeScript | ts-v0.1.0, ts-v0.1.1, ... |
npm |
To cut a release:
-
Bump the version in the relevant package manifest (
python/pyproject.tomlortypescript/package.json). -
Update
CHANGELOG.mdwith the new entry. -
Tag and push:
# Python release git tag py-v0.2.22 git push origin py-v0.2.22 # TypeScript release git tag ts-v0.1.1 git push origin ts-v0.1.1
The publish.yml workflow inspects the tag prefix and only runs the matching publish job. Python uses PyPI's OIDC trusted publisher (no API token needed). TypeScript publishes via the NPM_TOKEN repo secret.
Tags must match py-v*.*.* or ts-v*.*.* exactly - GitHub Actions tag filters are globs, not regex, so the three dot-segments are required to gate the publish.
| Package | What it does |
|---|---|
asqav (PyPI) |
Python SDK |
@asqav/sdk (npm) |
TypeScript SDK |
| asqav-mcp | MCP server for Claude Desktop, Claude Code, Cursor |
| asqav-compliance | CI/CD compliance scanner |
Get started at no cost. Free includes 50K signatures/month, 20 agents, 10 policies, 3 team members, OpenTimestamps, MCP server, audit export, and framework integrations. Content scanning, OpenTelemetry, and Replay API on Pro. Quarantine, incident management, multi-party signing, compliance reports, and RFC 3161 timestamps on Business. Managed KMS, SSO, IP allowlist, and bring-your-own KMS on Enterprise. See asqav.com/pricing for the full breakdown.
Machine-readable service descriptor at https://asqav.com/.well-known/governance.json for external tools that want to auto-discover Asqav's endpoints, algorithms, capabilities, and integrations.
- Docs: https://asqav.com/docs
- Repo: https://github.com/jagmarques/asqav-sdk
- Integration docs: https://asqav.com/docs/integrations
- Blog: https://dev.to/jagmarques
- Dashboard: https://asqav.com/dashboard
MIT - see LICENSE for details.
If Asqav helps you, consider giving the repo a star. It helps others find the project.