Skip to main content

Creduent Protocol SDK - cryptographic identity for AI agents

Project description

Creduent Python SDK

PyPI version License Python Compatibility Downloads

The official Python SDK for the Creduent Protocol — a federated, open trust-verification layer and cryptographic identity infrastructure for autonomous AI agents.

Creduent enables autonomous agents to cryptographically sign metadata, verify identities across administrative domains via DNS bindings, and interact with the Creduent registry for secure, machine-to-machine trust checks.


Key Features

  • 🔑 Cryptographic Identity Management: Generate secure Ed25519 keypairs for AI agents.
  • ✍️ RFC 8785 Canonical Signatures: Compute cryptographic signatures over JSON agent documents using JCS and Ed25519.
  • 🛡️ SSRF Protection: Safe endpoint resolution blocking private/loopback network ranges.
  • 🔗 DNS Trust Binding: Verify cryptographic bindings between agent:// identifiers and web domains.
  • 🏛️ Registry Integration: Register agents and resolve signed attestations from the Creduent Registry.
  • 🛠️ CLI Utilities: Out-of-the-box CLI commands for signing, verification, and key generation.
  • ⚙️ Serverless-Safe Env Loader: Avoids .env interference in Vercel and other serverless environments.

Installation

pip install creduent

Architectural Flow

+------------------+             +----------------------+             +------------------+
|   Agent Domain   |             |   Creduent Registry  |             |   Agent Client   |
|   (agent.json)   |             |   api.idevsec.com    |             |    (MCP Host)    |
+------------------+             +----------------------+             +------------------+
         |                                |                                |
         |---- 1. Serve agent.json ------>|                                |
         |                                |-- 2. Verify identity & DNS --->|
         |                                |      and sign attestation      |
         |<--- 3. Query agent endpoint ------------------------------------|
         |                                |                                |
         |                                |<--- 4. Fetch attestation ------|

Registering Your Agent

Registration is open — no admin key required. Any developer can register an agent. After registration, your agent gets level: "unverified". Contact the registry admin for verified or trusted upgrade.

The backend runs 6 verification steps — all must pass:

Step 1 → Fetch agent.json from your agent_json_url
Step 2 → Validate schema (7 required fields)
Step 3 → Confirm agent_id matches in both form and file
Step 4 → Verify Ed25519 self-signature
Step 5 → Check DNS TXT record: _creduent.yourdomain.com
Step 6 → Health check your agent endpoint (must be live HTTPS)

Step 1 — Generate Ed25519 Keypair

from creduent import generate_keys

private_key_pem, public_key_str = generate_keys()

with open("private_key.pem", "w") as f:
    f.write(private_key_pem)

print(public_key_str)  # ed25519:ABC123...  ← goes in agent.json

Or via CLI:

creduent-sign generate-keys
# Saves: private_key.pem  (KEEP SECRET)
# Prints: ed25519:...     (public key)

Step 2 — Create agent.json

Create a draft with these required fields:

{
  "version": "1.0",
  "agent_id": "agent://yourorg/youragent",
  "owner": "Your Name or Organization",
  "public_key": "ed25519:ABC123...",
  "endpoint": "https://yourdomain.com/agent",
  "capabilities": ["task_execution", "file_read"]
}
Field Requirement
version Must be exactly "1.0"
agent_id Format: agent://<namespace>/<name> — lowercase, alphanumeric, hyphens
owner Any string
public_key Must start with ed25519:
endpoint Live public HTTPS URL (no localhost, no private IPs)
capabilities Array of strings
signature Added in next step — do not add manually

Step 3 — Sign agent.json

from creduent import sign
import json

with open("draft_agent.json") as f:
    draft = json.load(f)

with open("private_key.pem") as f:
    private_key_pem = f.read()

signed_doc = sign(draft, private_key_pem)

with open("agent.json", "w") as f:
    json.dump(signed_doc, f, indent=2)

Or via CLI:

creduent-sign sign \
  --key private_key.pem \
  --input draft_agent.json \
  --output agent.json

Important: Re-sign every time you modify agent.json. Any change to the document invalidates the signature.


Step 4 — Host agent.json

Serve the signed file at a public HTTPS URL. Recommended path:

https://yourdomain.com/.well-known/agent.json

Requirements:

  • HTTP 200 response
  • Content-Type: application/json
  • No auth, no VPN, no private IPs — must be publicly reachable

Cloudflare Users — Required Configuration

If your domain is proxied through Cloudflare (orange cloud), you must add a WAF rule before registering. Without this, Cloudflare will block the Creduent registry server from fetching your agent.json and health-checking your endpoint, returning HTTP 403.

Rule 1 — Allow Registry Fetch and Endpoint Health Check

Cloudflare Dashboard → Security → Security Rules → Custom Rules → Create Rule

Name: Allow Creduent Manifest and Endpoint Field: URI Path Operator: is in Value:

  • /.well-known/agent.json
  • /<your-agent-endpoint-path> (e.g. /agent or /api/agent) Action: Skip Skip: All remaining custom rules + All rate limiting rules + All managed rules Place at: First

DNS TXT Record (Cloudflare)

When adding the _creduent TXT record in Cloudflare DNS:

  • Make sure the orange cloud (proxy) is OFF for the TXT record
  • TXT records do not need to be proxied
  • TTL: Auto

Common Cloudflare Errors

Error Cause Fix
Failed to fetch agent.json: HTTP 403 Cloudflare WAF blocking registry server Add the WAF rule above
Failed to fetch agent.json: HTTP 403 (after adding rules) Bot Fight Mode JS challenge Disable JS Detections under Security → Bots
Registration succeeds but resolver shows 403 CSP blocking api.idevsec.com Add api.idevsec.com to connect-src in your site's CSP headers

Step 5 — Add DNS TXT Record

Proves domain ownership. Add this to your domain's DNS:

Type Name Value
TXT _creduent agent://yourorg/youragent

Full record name: _creduent.yourdomain.com

Verify propagation (~5 min):

# Windows
nslookup -type=TXT _creduent.yourdomain.com

# Linux / Mac
dig TXT _creduent.yourdomain.com
# Expected: "agent://yourorg/youragent"

Step 6 — Register

from creduent import register

result = register(
    agent_id="agent://yourorg/youragent",
    domain="yourdomain.com",
    agent_json_url="https://yourdomain.com/.well-known/agent.json"
)

if result.success:
    print(f"Registered! Level: {result.attestation['level']}")
    # → Registered! Level: unverified
else:
    print(f"Failed: {result.error}")

Or via curl:

curl -X POST https://api.idevsec.com/registry/register \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "agent://yourorg/youragent",
    "domain": "yourdomain.com",
    "agent_json_url": "https://yourdomain.com/.well-known/agent.json"
  }'

Success response:

{
  "agent_id": "agent://yourorg/youragent",
  "issuer": "agent://creduent/registry",
  "level": "unverified",
  "issued_at": "2026-05-31T00:00:00Z",
  "expires_at": "2027-05-31T00:00:00Z",
  "public_key": "ed25519:...",
  "domain": "yourdomain.com",
  "signature": "...",
  "status": "registered"
}

Common Registration Errors

Error Cause Fix
Failed to fetch agent.json: HTTP 404 File not at URL Check URL is public and returns 200
Missing required field 'signature' Draft not signed Run creduent-sign sign first
agent_id in agent.json does not match Mismatch in form vs file Use exact same string in both
Cryptographic signature is INVALID File modified after signing Re-sign with creduent-sign sign
DNS TXT record not found (NXDOMAIN) TXT record missing Add _creduent TXT to your DNS
does not contain agent_id Wrong TXT value Value must be exactly agent://yourorg/youragent
Endpoint healthcheck failed Endpoint unreachable Is your server live? Public HTTPS?
429 Too many requests 5/hour rate limit Wait 1 hour and retry

Registration Checklist

[ ] Ed25519 keypair generated (private_key.pem + public key)
[ ] draft_agent.json created with all required fields
[ ] agent.json signed (signature field present)
[ ] agent.json hosted at a public HTTPS URL
[ ] DNS TXT record added: _creduent.yourdomain.com = agent://yourorg/youragent
[ ] DNS propagated (verified with nslookup or dig)
[ ] register() called → status: "registered" received

Quickstart (Full Example)

from creduent import generate_keys, sign, verify, register, attest, CreduEntError

try:
    # 1. Generate keypair
    private_key_pem, public_key_str = generate_keys()

    # 2. Sign a draft agent.json
    draft = {
        "version": "1.0",
        "agent_id": "agent://creduent/reconbot",
        "owner": "IDevSec",
        "public_key": public_key_str,
        "endpoint": "https://api.idevsec.com/recon",
        "capabilities": ["osint", "dns_lookup"]
    }
    signed_doc = sign(draft, private_key_pem)

    # 3. Verify self-signed document
    result = verify(signed_doc)
    print(f"Self-verify: {result.valid}")

    # 4. Register with registry (requires DNS + hosted agent.json)
    reg = register(
        agent_id="agent://creduent/reconbot",
        domain="api.idevsec.com",
        agent_json_url="https://api.idevsec.com/.well-known/agent.json"
    )
    print(f"Registered: {reg.success}, Level: {reg.attestation['level']}")

    # 5. Query attestation
    att = attest("agent://creduent/reconbot")
    print(f"Attested: {att.attested}, Level: {att.level}")

except CreduEntError as e:
    print(f"Error: {e}")

Challenge-Response Authentication

Allows agents to prove their cryptographically registered identity to other agents.

# Agent proving its identity to another agent
from creduent import challenge

# Agent side — prove identity
proof = challenge.create_proof(
    agent_id="agent://cyberhavox/havox-ai",
    private_key_pem=open("private_key.pem").read()
)
# proof = {"verified": True, "level": "trusted", "proof_token": "...", "valid_until": "..."}

# Receiver side — verify the proof
is_valid = challenge.verify_proof(
    proof_token=proof["proof_token"],
    agent_id="agent://cyberhavox/havox-ai"
)
print(is_valid)  # True

Command Line Interface

creduent-sign

# Generate Ed25519 keypair
creduent-sign generate-keys

# Sign a draft agent.json
creduent-sign sign --key private_key.pem --input draft_agent.json --output agent.json

creduent-verify

# Verify a local file
creduent-verify agent.json

# Verify by URL
creduent-verify https://yourdomain.com/.well-known/agent.json

# Verify by domain
creduent-verify yourdomain.com

# Verify by agent:// URI
creduent-verify agent://creduent/reconbot

API Reference

generate_keys() → (private_key_pem: str, public_key_str: str)

Generates a new Ed25519 keypair. Returns PEM private key and ed25519:-prefixed public key.

sign(draft: dict, private_key_pem: str) → dict

Signs a draft agent.json using JCS canonicalization (RFC 8785) + Ed25519. Returns signed document with signature field.

verify(target: str | dict) → VerifyResult

Verifies a self-signed agent.json. Accepts dict, HTTPS URL, domain, local path, or agent:// URI.

  • result.valid — bool
  • result.agent_id, result.public_key, result.endpoint, result.capabilities
  • result.error — str or None

register(agent_id, domain, agent_json_url, registry_url?) → RegisterResult

Registers an agent with the Creduent registry.

  • result.success — bool
  • result.attestation — dict (level, issued_at, expires_at, ...)
  • result.error — str or None

attest(agent_id, registry_url?) → AttestResult

Fetches attestation status for an agent from the registry.

  • result.attested — bool
  • result.level"unverified" | "verified" | "trusted"
  • result.issued_at, result.expires_at
  • result.error — str or None

challenge.create_proof(agent_id, private_key_pem, registry_url?) → dict

Initiates a cryptographic challenge-response authentication flow to generate an identity verification proof.

  • Returns dict containing proof_token, verified status, level, valid_until timestamp, and issuer.

challenge.verify_proof(proof_token, agent_id, registry_url?) → bool

Decodes the proof token and verifies its authenticity using the registry's public key. Returns True if valid and not expired, False otherwise.


Advanced Utilities

SSRF Protection

from creduent.utils import safe_requests_get

response = safe_requests_get("https://example.com/.well-known/agent.json", timeout=5)

Blocks private IPs (RFC 1918), loopback, and link-local addresses before connecting.

Serverless Environment Loader

from creduent.utils import load_dotenv

load_dotenv()  # Skips loading in Vercel (VERCEL=1) to avoid clobbering prod env vars

Changelog

v0.4.1 (Current)

  • Normalized pyproject.toml line endings from CRLF (\r\n) to LF (\n).
  • Fixed metadata inconsistency by adding python_requires=">=3.10" to setup.py (matching pyproject.toml).
  • Replaced the invalid {text = "Apache-2.0 OR Commercial"} SPDX expression in pyproject.toml with license-files declaration to properly package LICENSE, LICENSE-APACHE, and LICENSE-COMMERCIAL for PyPI.
  • Created initial CHANGELOG.md tracking detailed package version history.

v0.4.0

  • Changed project license from MIT to Dual Licensing (Apache-2.0 and Commercial License).
  • Updated package author metadata to IDevSec.
  • Removed FastAPI dependency from client SDK/CLI.
  • Added Challenge-Response Authentication feature: challenge.create_proof and challenge.verify_proof.
  • Added dynamic public key query endpoint /registry/public-key to registry.
  • Added outbound SSRF-protected POST helper safe_requests_post.

v0.2.3

  • Refactored safe_requests_get to fetch the original URL directly with verify=True enabled for secure SSL verification.
  • Synced the SSRF safety request client between the Vercel registry server and Python SDK.

v0.2.2

  • Added custom headers support (User-Agent and Accept: application/json) to the registry's agent verification fetch requests.

v0.2.1

  • Complete registration guide added to README: 6-step pipeline, DNS TXT setup, error table, and checklist.
  • Fixed function name documentation (register, attest, verify, sign).

v0.2.0

  • Replaced requests.get with safe_requests_get for SSRF protection.
  • Added comprehensive Google-style docstrings and type hints.
  • Updated documentation and simplified CLI usage.

v0.1.5

  • Internal beta release with security features and docstring polish.

v0.1.2

  • Initial release: core signing, verification, and registration logic.

Contributing

Bugs, feature requests, and pull requests welcome via GitHub Issues.


License

Dual Licensed under Apache License 2.0 (Open Source) and Commercial License — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

creduent-0.4.1.tar.gz (29.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

creduent-0.4.1-py3-none-any.whl (26.0 kB view details)

Uploaded Python 3

File details

Details for the file creduent-0.4.1.tar.gz.

File metadata

  • Download URL: creduent-0.4.1.tar.gz
  • Upload date:
  • Size: 29.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for creduent-0.4.1.tar.gz
Algorithm Hash digest
SHA256 889f9639e175c2995eff777fede796ef3ab21461ed587c0ac5e93bae4fcb75dc
MD5 7146963d6e94c8eef288408dd3b22e06
BLAKE2b-256 04f7204e57c5816d3eb54554ae1c7d81cd84fa65334b524d6744e1ac21f8a614

See more details on using hashes here.

File details

Details for the file creduent-0.4.1-py3-none-any.whl.

File metadata

  • Download URL: creduent-0.4.1-py3-none-any.whl
  • Upload date:
  • Size: 26.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for creduent-0.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 71750dfa415447f857b29f900dc245a17c42e859af1be6e6adaa62ce6756f153
MD5 3a6b9a94c469be368885dce9abb8f4cd
BLAKE2b-256 e46ef12dbcb30243bb0e8aa3c18fcfc50d86a57a49ee207e7caeba8adacc4326

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page