Skip to main content

Kredent logo

Kredent

CI PyPI Python License: Apache-2.0

Identity and verifiable reputation for autonomous agents.

Kredent gives a software agent a cryptographic identity it controls, lets it sign claims about what it did, and lets anyone verify those claims offline — with no registry, no resolver and no network access.


Why

Agents are starting to transact on their own: calling APIs, negotiating prices, making payments, deploying code. The infrastructure for this is being built quickly, and it has a gap at its centre. It is straightforward to answer "was this call authorised?" It is much harder to answer "who, exactly, made it, and should I trust them?"

An API key answers the first question and fails the second. A key is a bearer secret: whoever holds it can act as the agent, it says nothing about the agent's history, and it stops being meaningful the moment it is rotated or leaked. Every agent starts from zero on every new service, and no service can tell a reliable agent from a careless one.

Kredent's position is that this is an identity problem before it is a payments problem. Before an agent can be trusted to spend, it has to be identifiable across services in a way that is not controlled by any one platform. That requires an identifier that is portable by construction, and a history that is verifiable by anyone rather than held inside a proprietary scoring system.

Two choices follow from that, and they are the whole of the design:

  • Identifiers are did:key. The identifier is derived from the agent's own public key, so it is self-resolving: anyone can recover the verification key from the identifier alone, offline, with zero infrastructure. No platform issues it and no platform can revoke it.
  • History is a signed ledger, not a score. An agent's reputation is a deterministic function of public, signed events. Any party can recompute it and confirm the number they were given is real, rather than trusting a platform's internal metric.

What it is

A small Python library, a CLI, and an MCP server. Four operations:

Operation What it does
create Generates an Ed25519 keypair and a did:key identity.
attest Signs a claim, producing a self-contained attestation.
verify Checks an attestation offline. Signature, key binding, integrity, expiry.
reputation Computes a reputation score from a ledger of events.

The signatures are Ed25519 (RFC 8032) over a JCS-canonical serialization (RFC 8785), following the W3C Data Integrity proof pattern. Request-level authentication uses RFC 9421 HTTP Message Signatures.


In 30 seconds

pip install kredent

kredent create --name billing-bot          # an agent gets a did:key identity
kredent attest --name billing-bot \
    --claim '{"action":"deployed","service":"billing-api"}' \
    --out attestation.json                  # it signs a claim about what it did
kredent verify attestation.json             # anyone checks it — offline, no registry

The verification above runs with no network and no account: the public key is recovered from the did:key inside the document, so the file is the only input.


Install

pip install kredent

Or from a checkout:

git clone https://github.com/goun7/Kredent.git
cd Kredent
pip install -e .

The core library has a single runtime dependency, the audited cryptography library, used for Ed25519. That dependency is optional in practice: the package bundles a pure-Python Ed25519 implementation that is used automatically when cryptography is absent, so kredent verify works on a machine with nothing else installed.

The MCP server additionally needs the mcp package:

pip install "kredent[mcp]"

Quickstart

Create an identity:

$ kredent create --name billing-bot --controller did:web:acme.example
{
  "status": "stored",
  "name": "billing-bot",
  "agent_id": "did:key:z6MkhFUK6cNkNboTWN4VpRdKnMnH6y2RTXYFG6ve2EbziP7F",
  "public_key_multibase": "z6MkhFUK6cNkNboTWN4VpRdKnMnH6y2RTXYFG6ve2EbziP7F",
  "identity_document": { ... },
  "note": "The 32-byte seed was written to the local store with 0600 permissions. ..."
}

Sign a claim:

$ kredent attest --name billing-bot \
    --claim '{"action":"deployed","service":"billing-api","version":"1.4.2"}' \
    --out attestation.json
wrote attestation.json

Verify it — anywhere, offline, with nothing but the file:

$ kredent verify attestation.json
{
  "valid": true,
  "status_code": 200,
  "agent_id": "did:key:z6MkhFUK6cNkNboTWN4VpRdKnMnH6y2RTXYFG6ve2EbziP7F",
  "message": "Attestation verified: signature valid over canonical document"
}

That verification needs no network and no registry lookup. The public key is recovered from the did:key in the attestation itself, so the only input is the document you were handed.

Score an agent from a ledger of events:

$ kredent reputation did:key:z6MkhFUK... \
    --transactions 40 --total-claims 30 --refuted-claims 2
{
  "agent_id": "did:key:z6MkhFUK...",
  "reputation": {
    "score": 0.6407,
    "tier": "TIER_B",
    ...
  }
}

Verification also reads from stdin, so it composes with anything:

cat attestation.json | kredent verify

A worked Python example

from kredent import generate_seed, create_attestation, verify_attestation

seed = generate_seed()                      # the root secret; keep it safe
att = create_attestation(
    seed,
    claim={"action": "deployed", "service": "billing-api", "version": "1.4.2"},
)

# Hand the attestation to anyone. They need nothing else to check it.
result = verify_attestation(att.to_json())
assert result.valid
print(result.agent_id)                      # -> did:key:z6Mk...

Using it with an MCP host

Kredent ships an MCP server exposing the same four operations as tools, so an agent can manage its own identity during a session.

{
  "mcpServers": {
    "kredent": {
      "command": "kredent-mcp"
    }
  }
}

The tools:

Tool Purpose
create_identity Generate a persistent did:key identity.
attest Sign a claim with a stored identity.
verify Verify an attestation offline.
reputation Compute a reputation score from events.

By default create_identity persists the seed locally with 0600 permissions and never returns it over the transport. Passing persist: false returns the seed once, for the caller to route into a secrets manager — nothing is written to disk in that mode.


How reputation works

Reputation is not an opaque score. It is a published formula over a public ledger, so it can be recomputed and audited by anyone.

score = base_score × integrity_multiplier × volume_damping
  • base_score — a weighted blend of reliability (0.40), accuracy (0.30) and stability (0.15), normalised to 1.0.
  • integrity_multiplier — max(0, 1 - 0.5 × contradiction_rate), so a history of refuted claims costs.
  • volume_damping — 1 - exp(-n/30), the cold-start term.

Three consequences worth knowing:

A new identity cannot look established. With one transaction an agent reaches about 3% of its nominal score. Farming a fake history is therefore slow and expensive, and an agent that discards its identity to reset a bad reputation starts again from near zero.

Lying costs more than honesty pays. A contradiction carries twice the weight of a confirmation, so the expected value of fabricating a history is negative.

Praise from nobodies is worth almost nothing. Each event is weighted by the counterparty's own reputation, so a ring of fresh identities confirming one another accumulates almost nothing. A share of volume concentrated in a single counterparty is flagged as a collusion pattern.

Tiers are thresholds on the score: TIER_A (≥ 0.85 with no refuted claims), TIER_B (≥ 0.60), TIER_C (≥ 0.30), else QUARANTINED.


Security model

The seed is the identity. A 32-byte Ed25519 seed is the root of everything: anyone holding it can sign attestations as that agent, and there is no recovery. Treat it as a credential. Kredent never writes it anywhere unless asked, writes it with 0600 permissions when it does, and never returns it over the MCP transport unless you explicitly request it.

Verification is offline and keyless. kredent verify performs no network calls. It recovers the public key from the did:key in the document, so a verifier has nothing to compromise and no resolver to attack.

Every forgery path is a test case. Tampering with the claim, the issuer, the attestation id, or swapping in a signature from a different key are all rejected with a distinct error code. The test suite pins these behaviours.

Known limitations, stated plainly:

  • A did:key cannot be rotated or revoked. A compromised seed permanently burns the identity and its history. There is no remediation path within the protocol. For a long-lived agent that must survive key compromise, did:web would be the better method, and nothing prevents an operator from running that underneath.
  • The protocol establishes who signed a claim and that it is unaltered. It does not establish that the claim is true. Grounding in reality requires evidence from outside the protocol.
  • Reputation measures whether claims were confirmed or contradicted by parties willing to say so. It does not measure whether an agent's output was good; that is a judgement for a human or an evaluating model.
  • Ed25519 is not post-quantum. The proof format carries an explicit cryptosuite field so a future suite can be introduced without changing the document model.
  • The bundled pure-Python Ed25519 exists so verification works with zero dependencies. It is correct and cross-validated against cryptography and the RFC 8032 test vectors, but it is not constant-time and is not intended for high-volume signing. Install cryptography for that.

Repository layout

kredent/             Core library
  crypto.py          Ed25519, base58btc, multibase, did:key resolution
  models.py          AgentID, Attestation, ReputationScore, ledger events
  canonical.py       JCS (RFC 8785) and RFC 9421 canonicalization
  attest.py          Attestation issuance and offline verification
  reputation.py      Scoring engine and anti-gaming filters
  ledger.py          Append-only calibration ledger
  store.py           Local identity store (0600 secrets)
  verifier.py        RFC 9421 request verification with replay protection
  cli.py             The `kredent` command
  mcp_server.py      MCP server implementation
mcp/kredent_mcp.py   Entry point for the MCP server
tests/               Test suite
docs/arastirma/      Research notes on DIDs, reputation and signature schemes

Tests

pip install -e ".[dev]"
pytest

1.321 tests passed, 0 failed rc=0 (LEED-ölçümü 2026-10-19, pytest tests/), covering the attestation lifecycle, every forgery path, did:key round-tripping, JCS determinism, reputation math and anti-gaming filters, the CLI as real subprocesses, and the MCP server over an actual JSON-RPC stdio session.


Research notes

The design decisions above are grounded in documented specifications. Notes and sources are in docs/arastirma/:


Status

Working core. The attestation format is stable; the reputation model is still being tuned against real event data and its weights may change. Do not treat a reputation score as a decision-making oracle yet.

License

Apache-2.0. See LICENSE.

Academic & technical references

  • Verifiable credentials — Kredent issues an agent a cryptographic identity it controls, plus reputation others can verify without trusting the issuer's word. This is the verifiable-credentials pattern: issuer, holder, verifier — the holder presents, the verifier checks, the issuer cannot silently revoke what was already shown.
  • Decentralized identifiers (DIDs) — the identity primitive x402's own ecosystem converged on: x402 #1777 (agent-trust DID, 119 comments). Mesh implementation lives in 63-Sester sester/trust.py (did:sester: prefix, attestations, trust-tiered pricing).
  • Reputation with wash-trade resistance — a raw count of completed transactions is gameable: two wallets under one party can settle real value back and forth forever and manufacture "activity." The countermeasure is diversity (distinct counterparties or resources per transaction); see x402 #2833 ("volume is not trust") and Sester's wash_resistant_score.
  • Privacy property: Kredent's reputation is presented per-attribute — an agent proves a property about its history without exposing the whole history. Selective disclosure, not full exposure.

Current academic references (2024–2026)

The patterns above, as they appear in the 2024–2026 literature:

  • Lookup-private credential status verification (2026) — Herbke, Rieder, Sechting vd. "ShadowPath: Lookup-Private Credential Status Verification over Authenticated State." (arXiv 2608.19937): checking whether a credential is still valid without the issuer learning who is checking — Kredent's "verify without trusting the issuer's word" property with the privacy half made explicit.
  • Private credential inference (2026) — Breckenridge, Vilardell, Leung vd. "$π$Creds: Privately Inferred Credentials." (arXiv 2606.03771): deriving a credential's content without disclosing it — the selective-disclosure primitive Kredent's per-attribute reputation uses.
  • Verifiable credentials in privacy-preserving federated analytics (2026) — Drăgnoiu & Olimid. "On the Usage of Verifiable Credentials in Privacy-Preserving Federated Analytics." (arXiv 2609.33004): issuer/holder/verifier separation as it is applied when the holder must not expose the underlying data.
  • Verifiable provenance with limited disclosure via ZKPs (2026) — Hrabar, Arshadi Soufiani, Kim vd. "OreProof: Verifiable Provenance with Limited Disclosure for Critical-Minerals Supply Chains Using Zero-Knowledge Proofs." (arXiv 2609.00340): prove a chain-of-custody claim without revealing the custody history — the shape of Kredent's reputation attestation.
  • DIDs for agents (2026) — Garzon, Vaziry, Kuzu, Gehrmann. "AI Agents with Decentralized Identifiers and Verifiable Credentials." (DOI 10.5220/0014234400004052, ICAART): the issuer/holder/verifier pattern applied to autonomous agents — the population Kredent attests to.

Metadata

Release files for kredent 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for kredent 1.0.0
File Size Uploaded
kredent-1.0.0.tar.gz 109.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for kredent 1.0.0
File Interpreter ABI Platform
kredent-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 154.9 kB

Release files / kredent-1.0.0.tar.gz

Download URL kredent-1.0.0.tar.gz
Size 109.3 kB
Tags Source
SHA-256 checksum
How to use checksums
f66f903826205e3f95f8e2141eaa652c5dbd8f8967da6b26485a12e61b3c6895
BLAKE2b-256 checksum
How to use checksums
91f3ad22d1a182e2f376297d17d911187f6d34caca7a5879ad1ccbd9ae74e8c3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.8

Release files / kredent-1.0.0-py3-none-any.whl

Download URL kredent-1.0.0-py3-none-any.whl
Size 45.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
355fdcbb247ed7eb5ffc4f82e5e2f4ba2298b4d646f735fbcd90ca51f4f8a589
BLAKE2b-256 checksum
How to use checksums
d88283f15a7caf55ccfffba4c446e17149adfdf2937efe819e9436845fe2d77c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.8

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page