An identity and a mandate going in. A recomputable record coming out — verify it yourself, or hand it to a partner, a bank, or an auditor.
Email only, no card — 100 credits on registration. An agent with a keypair can skip the mailbox: keyless onboarding for agents → 🇨🇳 中文文档
One call: a W3C identity, a signed credential, an on-chain anchor. Add an AAE mandate — what the agent may do, up to which limit.
Every action becomes a MoltProof — hashed, batched, anchored on Base L2. Recomputable by anyone, later.
Check a credential offline against Base L2, no key. Hand a recomputable proof to a partner, a bank, or an auditor.
Three steps, three copy-paste blocks, ending in a real signed verdict. Every path below is verified live against the MolTrust API v1.
Email only, no card. Returns a key with 100 credits.
Costs no credits. Returns a full signed AgentTrustCredential + 100 credits. Trust score is withheld until the agent has ≥3 endorsements — how an agent qualifies without them →
Public, no key. This returns a real signed score payload from the network.
One line of trust verification, any framework. Pick yours — install, then read the setup guide.
Verify agents at your API with @moltrust/sdk middleware.
Trust check before every tool call — one guardrail.
Middleware for create_agent — gate by trust score.
Request interceptor for A2A remote agents.
Same IPR evidence — anchored or attested. The attested path needs no chain access.
53 tools for trust verification, scoring & credentials at the hosted endpoint; 48 in the pip package.
Trust verification before every tool call — one line. Read the walkthrough →
Benefit first. Pick by what you're building — each is an independent install.
Use it when you want to gate agents at your API — Express / Hono / Fastify: verify(), register(). Pulls in @moltrust/aae.
Use it when you want to verify credentials offline — W3C VC + IPR against Base L2. No MolTrust API key.
Use them when you want to gate paid endpoints — x402 payments, or MPP (Stripe / Tempo / Visa). Same requireScore() shape.
Use it when you want to author or validate an AAE — schema + runtime validator. Already pulled in by the SDK.
Use it when you want to react when trust changes post-onboarding — CAEP Profile v1 event-reactive layer.
Use it when you want to check a transaction against a signed mandate before your agent acts — and recompute the answer yourself instead of trusting ours.
Use them for an agent runtime (OpenClaw plugin) or an MCP client (Claude, etc., PyPI).
@moltrust/verify and @moltrust/agent-firewall are standalone consumer libraries — no MolTrust API key. @moltrust/sdk declares @moltrust/aae as a dependency, so installing the SDK pulls AAE in automatically.
moltrust-enforceA Python client that answers one question before your agent acts: does this transaction fall inside the mandate its principal signed? The answer is PERMIT, DENY or PENDING. It runs on your side, inside your own agent runtime — no decorator, no framework hook, you decide where the call goes.
The verdict depends on the mandate and the transaction, nothing else — no server state, no clock, no database. That is what makes the second call worth having: check() asks us, verify() recomputes the same verdict on your machine and compares. A hash that a party can recompute for itself (a digest — a short fingerprint of the inputs) is what turns our answer into something you can audit rather than accept. If the two disagree, you hear about it.
Fail-closed throughout: an unreachable server, an error status or an unreadable answer all come back as DENY. Nothing here turns a failed check into permission.
The key is the same one the rest of this page uses — grab a free one above if you have not already. /enforce/check authenticates exactly like /vc/aae/evaluate.
exactFull equality on a field. No prefix, no case-folding — a vanity address sharing the first characters is denied.
enumMembership in a listed set, each member compared in full.
rangeClosed integer interval, lo and hi included. Floats are rejected — they break recomputability.
A PERMIT requires a grant whose action_binding matches, all its constraints holding, and disposition: "allow". An action no grant addresses is denied, never held. PENDING comes only from an explicit "hold", and the client never resolves it for you. Every verdict carries a per-predicate trace: which check ran, on what value, against which bound. PyPI → · Source →
One line gates a paid endpoint by trust score. Same requireScore() API for both @moltrust/x402 (x402 payments) and @moltrust/mpp (MPP — Stripe / Tempo / Visa). Untrusted agents get a 403 before they transact.
1. ExtractWallet from the x402 / MPP payment header.
2. ScoreMolTrust trust score (5-min cache, <10ms warm).
3. Gate403 + registration link if below threshold.
Every x402 wallet also gets an automatic Wallet Trust Profile (shadow score, history, projected score after registration): GET https://api.moltrust.ch/wallet/{address} · public page /wallet/{address}.
Same identity, same mandate, same MoltProof. What differs is where the proof lives — and how strong the claim is.
Every record is anchored on the public chain and recomputable by anyone, for years. The proof stands on the chain — no trust in us required. Default for global on-chain agents.
No blockchain, no VPN — for regulated markets (China, India) and OpenClaw deployments without chain access. Records are verifiable against MolTrust's signed log, not recomputable from the public chain; you're trusting our signature. It is the weaker guarantee — use it where the chain isn't reachable.
Not needed to start. Open a topic when you want it.
null, not 0A freshly registered agent does not start at a fixed grade. Until it has at least three endorsements, its score is withheld — GET /skill/trust-score/{did} reports it as null, not 0. That is the expected starting state, not an error. Grades run S / A / B / C / D / F over a 0–100 score.
AAE is configured via POST /delegation/configure after registration — a machine-readable permission contract your API can inspect. The credential from /identity/register does not embed it.
Protocol Whitepaper v0.8 → · did:moltrust Method Specification →
Under the hood, a MoltProof is an Interaction Proof Record (IPR). Every agent action can produce one — IPRs are Merkle-batched and anchored on Base L2.
POST /vc/ipr/submitSubmit an IPR. Provide output_hash (SHA-256), agent_did, and confidence score. Returns ipr_id.
GET /vc/ipr/{ipr_id}Retrieve an IPR by ID. Returns output_hash, anchor status, Merkle proof, and Base L2 transaction hash.
POST /vc/ipr/verifyVerify an IPR: checks signature, on-chain anchor, and Merkle proof. Returns validity + anchor TX link.
GET /vc/ipr/agent/{did}List all IPRs for an agent. Paginated. Returns proof records with anchor status and Merkle proofs.
GET /vc/ipr/statsNetwork-wide IPR statistics: total records, anchored count, unique agents, average confidence score.
GET /vc/ipr/{ipr_id}/statusAnchor status of a specific IPR: pending, anchored, or failed. Includes retry count and block number.
“Anchored on Base L2” is only worth something if you can check it without us. This is the whole encoding: what goes into a leaf, how the tree is built, and what ends up in the transaction.
An anchor is a zero-value self-send — the anchoring address sends 0 wei to itself and the payload is the entire input field. No contract, no event, no storage. The calldata is ASCII, UTF-8 encoded, with no ABI wrapper:
The first four bytes of a credential anchor are 0x4d6f6c54. That is the letters MolT, not a function selector.
SHA-256 over five fields joined by |, with no spaces and no trailing separator:
From the credential document you hold, that is evidence[0].credentialId, credentialSubject.id, the entry of type[] that is not VerifiableCredential, proof.created with its UTC designator removed (a trailing Z, or +00:00), and proof.proofValue.
Read the timestamp from proof.created rather than the top level. Credentials exist under both W3C data model versions, which name that field validFrom and issuanceDate respectively; proof.created is in both.
Plain binary SHA-256 over the raw 32-byte digests — no domain separation, no sorted pairs, no length prefix. Leaves are ordered oldest first. If the number of leaves is odd, the last leaf is duplicated before anything else, so a one-credential batch is two leaves and its root is SHA-256(leaf || leaf), never the leaf itself. Each level above is padded the same way, and a parent is SHA-256(left || right).
Transaction 0xa5f77cb7…, block 51 604 928, three credentials — odd, so the padding is visible:
verify_anchor.py is the same thing in 140 lines. It imports nothing from our codebase, needs no API key, and reads a public RPC endpoint:
Full specification, including the interaction-proof-record variant and the edge cases: anchor-commitment.md.
A matching root proves these exact field values existed no later than the block that carried them. Change one character anywhere and the leaf, the root and the calldata all stop agreeing. It says nothing about whether the claim in the credential is true, whether the signature over it verifies, or whether it has since been revoked — those are separate checks, and all of them have to pass. Nor does the chain enumerate what was never anchored: an unanchored credential is unanchored, not refuted.
Email signup is rate limited to two new agents per /24 per 24 hours. That is deliberate — an address and a network are cheap to acquire, so they are what the Sybil cost is priced against. It also means a CI runner, a corporate NAT or a single cloud region runs out after two.
The keyless path is gated by proof-of-work instead of by your network, so it does not care how many agents share an address. Three calls, no account, no email:
GET /identity/register-challengeReturns a challenge string and a proof-of-work seed with its difficulty in bits. Free.
POST /identity/register-popGenerate an Ed25519 keypair, solve the proof-of-work, sign the challenge, post the four values. Returns a did:moltrust: and a signed credential. Currently 18 bits — a fraction of a second.
public_key is the raw 32-byte Ed25519 key as 64 hex characters, upper or lower case, stored lower case. Base64, base58, multibase and a 0x prefix are all rejected — the 422 names the encoding it wanted.
POST /auth/signup-didBinds an API key to that DID, using the same keypair and proof. Without this step the DID has nothing to authenticate with, and paid endpoints answer 401.
Ten versioned checks over a SKILL.md, each mapped to a CWE identifier with a stated deduction. The check list and its version are public, so a verdict can be reproduced later rather than taken on trust.
Where the line runs: finding out about your own skills is free — audit, verify, read the check list. Showing a third party a signed credential is what you pay for.
GET /guard/skill/audit?url=<repo>Free, no API key, 5 per hour per IP. Returns score, findings, canonical skill hash and auditor version. Add &profile=claude_skill for Claude Agent Skills. 404 means the repository has no SKILL.md.
GET /guard/audit/checksFree. Every check with severity, deduction and CWE reference. GET /guard/audit/version returns the version and checksum the verdict was produced under.
GET /guard/skill/verify/{skillHash}Free. Resolve a previously issued credential by the canonical hash of the skill file.
POST /guard/vc/skill/issuePaid — 5 USDC via x402. Issues a signed, on-chain-anchored VerifiedSkillCredential. This is the gate-use half: a verdict you hand to someone else.
Pre-execution safety check for order-sensitive action sequences. Opt-in, deterministic, no LLM calls. Phase 1: WARN-only.
POST /guard/api/action/checkCheck a proposed action against the session history. Returns verdict (SAFE/WARN/BLOCK), residual score, and conflicting action.
GET /guard/api/action/statsAggregated SAS statistics: total events, breakdown by verdict, average residual.
GET /guard/api/action/events/{did}SAS events for a specific DID. Shows all WARN/BLOCK events with residual scores and conflicting actions.
MolTrust supports a third enforcement layer via Falco eBPF — syscall-level monitoring that agents cannot bypass from userspace.
Layer 1 — CryptographicEd25519 signatures, JCS canonicalization. Tamper-proof by construction.
Layer 2 — APITrust score degradation, IPR submission, credential revocation.
Layer 3 — KernelFalco eBPF/syscall detection. Not bypassable by the agent process.
When a policy violation is detected at the kernel level, Falco fires a webhook to the MolTrust bridge, which submits an IPR violation record — trust score degrades automatically. Reference implementation →
Identity plus a one-time score check isn't enough: a counterparty you onboarded yesterday can be revoked or downgraded today. @moltrust/agent-firewall polls the registry's CAEP Profile v1 and fires typed events on trust-score changes and revocations, with the new score verified end-to-end (JCS + Ed25519) before your handler runs.
GET /caep/pending/{did}Cursor-based pending events. Rate limit 120 polls/h per DID (30 s interval, server-enforced).
POST /caep/acknowledge/{event_id}Idempotent soft-ack, 90-day retention.
GET /.well-known/registry-key.jsonEd25519 JWK for signature verification.
GET /skill/trust-score/{did}Signed score payload (JCS + Ed25519, kid moltrust-registry-2026-v1).
Polling-only (CAEP Profile v1, proprietary — not OpenID SET). Page size: server default limit=50 (max 500). Typed handlers fire only for cryptographically-verified events by default.
One line in your README. The badge fetches your live trust score automatically.
Your agent discovers, registers, and gets its credentials — without you in the loop. Point it at our agent-card and walk away. Every path below is verified live against the MolTrust API v1.
did:moltrust is the only supported DID method today; did:web and did:key are not accepted. You bring no key material in advance — POST /identity/register provisions your identifier and its Ed25519 signing key, publishes the public key in your DID document, and anchors it on Base L2.
A trust score is withheld until an agent has three endorsements, and an agent that registered this morning has none. A gate reading the score denies it, which is correct — a score nobody has computed is not a low score. It also leaves a new agent with nothing to present. A track record is what it can present instead: one credential stating what a wallet it controls has done on Base.
Two thresholds, both published here because a threshold that moves quietly is not one you can rely on:
nonce ≥ 1 | the wallet has sent at least one transaction of its own |
age ≥ 7 days | measured from its first transaction on Base |
chain = base | the history is read on Base and the credential is anchored there |
Neither threshold is a quality bar. They are a cost: a wallet that has sent a transaction and is a week old cannot be produced at the moment someone wants a discount. The first one is the one that catches people out — most agent marketplaces relay transactions gaslessly, so a wallet can have worked for weeks and still sit at nonce 0. Sending one transaction yourself is what clears it.
The credential carries the measured numbers — transactions sent, age in days, transfer count, USDC volume — next to the thresholds they were judged against, so a verifier can redo the judgement from the credential without asking us what the rule was that day.
A gate built on @moltrust/x402 or moltrust_enforce can accept a track record in place of a score it has never been given. The option is allowTrackRecord and it is off by default, so an existing gate keeps the behaviour its operator configured. MoltGuard has it on: 20 % off at score ≥ 50, or with an anchored track record.
A recorded run of the whole path, with the anchor transaction, both 402 amounts and the settled payment: gate proof, 2026-09-23 → — anchored in 0xf207a648…a5adc, Base block 51674415.
What that run does not show, stated there and repeated here. It shows that the path is walkable; it does not show that anyone wants to walk it — the caller was us, the endpoint is ours, and the 0.04 USDC went from our test wallet to our own payTo. The wallet cleared the age threshold with one day to spare, eight days against a threshold of seven. And the anchor was triggered by hand instead of waited for, so the run finished in one piece; in normal operation the batch runs every two hours and the wait is real.
Three things worth knowing before you rely on it. A track record stands in for a score nobody computed, never for one that was computed and came out low. It reaches the attestation only after the anchoring batch has run, which happens every two hours — anchor_tx is the field a relying party checks, and it cannot be filled in before the transaction exists. And the anchor is not confirmed in the request path: the signature over the attestation already covers those bytes, so a host that wants the chain checked as well reads anchor_tx and does it on its own schedule.
| Option | Type | Default | Description |
|---|---|---|---|
| minScore | number | 0 | Minimum trust score required to pass verification. Agents below this threshold receive a 403. |
| requireAAE | boolean | false | Require a valid Agent Authorization Envelope in the credential. Rejects agents without one. |
| evaluateAction | string | — | Check whether the AAE mandate permits this specific action (e.g. "purchase", "transfer"). |
| evaluateAmount | number | — | Evaluate AAE financial constraints against this transaction amount (USD). |
| evaluateJurisdiction | string | — | Verify the AAE permits operations in this ISO 3166-1 jurisdiction code. |
| apiBase | string | api.moltrust.ch | Override the MolTrust API base URL. Useful for staging or self-hosted deployments. |
Express + Hono middleware. AgentTrust.verify(), .middleware(), .register().
MCP server — 53 tools for trust verification, scoring, credentials. Install from PyPI, or connect the hosted remote through Smithery or Glama.
OpenClaw plugin — 2 agent tools, 2 slash commands, CLI, gateway RPC. Free tier included.
CAEP Profile v1 consumer — react to revocations, flag changes & trust-score updates. Signed trust-score verification (JCS + Ed25519).
Email only, no card. 100 credits on registration — enough to verify agents, issue credentials, and submit your first proof.
Attested MoltProofs for your OpenClaw agents — verifiable against MolTrust's signed log, not recomputable from the public chain; you're trusting our signature. Fully API-only: no blockchain, no VPN. All @moltrust/* packages on cnpm, compliant with CAC requirements.
MolTrust 提供 W3C DID/VC 信任基础设施,支持 OpenClaw 代理的身份验证、信任评分和可验证凭证。纯 API 模式,无需区块链,无需 VPN。
MolTrust provides W3C DID/VC trust infrastructure for AI agents. Pure API mode — no blockchain required, no VPN needed. All @moltrust/* packages available on cnpm. These are attested MoltProofs — verifiable against MolTrust's signed log, not recomputable from the public chain; you're trusting our signature. 这是经签名认证的 MoltProof(attested):对照 MolTrust 的签名日志验证,而非公链重算——即你信任我们的签名。