Skip to main content

Cryptographic identity for AI agents. Verifiable Ed25519 tokens replacing hardcoded API keys.

Project description

AgentID

Every AI agent in production today authenticates with hardcoded API keys. That's the equivalent of shipping a web app with password: admin. AgentID fixes this.

AgentID gives every AI agent a cryptographic identity — an Ed25519 keypair that acts as the agent's passport. Any service can verify "this request came from agent X, with scopes Y, and has not been tampered with" in under 0.1 ms, with zero network calls, zero key servers, zero JWT libraries.

pip install agentid-auth

Why not JWTs?

JWT was designed for human browser sessions. For machine-to-machine agent traffic, it's the wrong tool:

JWT (RS256) AgentID Token
Size ~800 bytes ~173 bytes
Verification ~0.4 ms (RSA) <0.1 ms (Ed25519)
Rate limits ❌ Not in spec ✅ Baked into the signed payload
Scopes String claim (not enforced) ✅ Cryptographically bound
Key discovery JWK endpoint required ✅ Offline, no network
Agent-native

The AgentID binary wire format (0xA9 0x1D magic) packs a complete token — issuer pubkey, scopes, TTL, call quota, and Ed25519 signature — into 173 bytes. Deserialisation and signature verification complete in a single cache-hot pass.


Installation

pip install agentid-auth

For framework integrations:

pip install agentid-auth[fastapi]     # FastAPI/Starlette middleware
pip install agentid-auth[langgraph]   # LangGraph middleware
pip install agentid-auth[crewai]      # CrewAI decorator
pip install agentid-auth[all]         # Everything

Quick Start

Python

from agentid import AgentIdentity, verify_token

# Derive a deterministic identity — same inputs → same keypair, every time.
identity = AgentIdentity("research-bot", "phd-lab")
print(identity.fingerprint)  # ag:sha256:022a6b57...

# Mint a compact binary token (~173 bytes, not 800 like JWT).
token = identity.mint_token(
    scopes=["read:arxiv", "write:notes"],
    ttl_seconds=900,
    max_calls=100,
)

# Verify offline. No network. No key server. <0.1 ms.
claims = verify_token(token, expected_pubkey=identity.public_key)
print(claims.name)       # research-bot
print(claims.permits("read:arxiv"))  # True

Rust

use agentid_core::{AgentIdentity, TokenBuilder, verify_token};

// Derive a deterministic identity from name + project.
// Same inputs → same keypair, every time, on every machine.
let identity = AgentIdentity::derive("research-bot", "phd-lab", None)?;

println!("public key : {}", identity.public_key_hex());
println!("fingerprint: {}", identity.fingerprint()); // ag:sha256:022a6b57...

// Mint a compact binary token — 173 bytes, not 800.
let token = TokenBuilder::new(&identity)
    .scopes(["read:arxiv", "write:notes"])
    .ttl_seconds(900)
    .max_calls(100)
    .build()?;

// Verify offline. No network. No key server. <0.1 ms.
let claims = verify_token(&token, Some(&identity.public_key()))?;

assert_eq!(claims.name, "research-bot");
assert!(claims.permits("read:arxiv")); // wildcard scope matching

CLI

# Initialise the local vault
agentid init

# Store an identity (encrypted with AES-256-GCM, password-derived via PBKDF2)
agentid keys add --name research-bot --project phd-lab

# Mint a token
agentid mint --name research-bot --project phd-lab \
  --scopes "read:arxiv,write:notes" --ttl 900 --max-calls 100

# Verify
agentid verify <token>
# Token verified.
#   name         research-bot
#   project      phd-lab
#   fingerprint  ag:sha256:022a6b577d76ae03
#   scopes       read:arxiv, write:notes
#   expires      2026-05-02T10:14:51.000Z
#   max_calls    100

# Start the optional gRPC server for centralised key management
agentid serve --port 6100

TypeScript / Bun

import { AgentIdentity, verifyToken, vault } from "agentid";

// Derive an identity
const id = AgentIdentity.derive("research-bot", "phd-lab");

// Mint
const token = id.mintToken({ scopes: ["read:arxiv"], ttlSeconds: 900 });

// Verify
const claims = verifyToken(token, id.publicKey);
console.log(claims.fingerprint); // ag:sha256:022a6b577d76ae03

Architecture

Token Wire Format

off  size  field
---  ----  -----
  0     2  magic          0xA9 0x1D
  2     1  version        0x01
  3     1  flags          0x00 (reserved)
  4     8  issued_at      i64 BE (unix seconds)
 12     8  expires_at     i64 BE
 20     4  max_calls      u32 BE  (0 = unlimited)
 24     8  token_id       u64 BE  (random nonce, replay protection)
 32    32  issuer_pubkey  Ed25519 (32 bytes)
 64   var  name, project, scopes  (u8 length-prefixed utf-8)
END    64  Ed25519 signature over bytes [0..END)

Every field is inside the signed region. A single byte flip anywhere causes verification to fail.

Deterministic Key Derivation

IKM   = name ‖ 0x00 ‖ project ‖ 0x00 ‖ seed?
salt  = b"agentid-v1"
info  = b"ed25519-signing-key"
okm   = HKDF-SHA256(salt, IKM, info, len=32)
sk    = Ed25519 SigningKey::from_bytes(okm)

The same (name, project) pair always produces the same keypair — reproducible across machines, no secret material to copy around.

Local Vault

Secret keys at ~/.agentid/keys/<fingerprint>.key:

  • KDF: PBKDF2-HMAC-SHA256, 200 000 iterations
  • Cipher: AES-256-GCM (nonce + tag per file)
  • Permissions: 0o600 (user-only)
  • Index: Unencrypted ~/.agentid/index.json (public metadata only — safe to back up)

Scope Matching

"read:arxiv"  →  matches exactly "read:arxiv"
"read:*"      →  matches "read:arxiv", "read:notes", ...
"*"           →  matches any scope
"*:papers"    →  matches "read:papers", "write:papers"

Feature Flags

Flag What it adds
server (default) Tonic gRPC server — agentid serve --port 6100
napi-bindings N-API cdylib for Node / Bun TypeScript SDK
# Core library only (no async runtime)
agentid-core = { version = "0.1", default-features = false }

# Default: core + gRPC server
agentid-core = "0.1"

Roadmap

  • v0.1 — Ed25519 identity, binary tokens, AES-256-GCM vault, gRPC server, TypeScript SDK, Bun CLI ✅
  • v0.2 — LangGraph + CrewAI framework middleware, token revocation list, key rotation
  • v0.3 — AgentID Cloud (hosted key management, audit log, team dashboard)

License

Apache License 2.0 — free for open-source and commercial use with attribution.

When using AgentID in a public project or product, you must give clear credit to the original author, Samvardhan Singh, in your documentation, README, or NOTICE file.

For enterprise use requiring white-labelling or a no-attribution obligation, contact the author for a commercial licence.

See LICENSE for the full text.


Three tools. Four launches. One platform. Ship the knife before you sell the kitchen.

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

agentidentity_auth-0.1.0.tar.gz (61.9 kB view details)

Uploaded Source

Built Distribution

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

agentidentity_auth-0.1.0-cp310-cp310-win_amd64.whl (483.0 kB view details)

Uploaded CPython 3.10Windows x86-64

File details

Details for the file agentidentity_auth-0.1.0.tar.gz.

File metadata

  • Download URL: agentidentity_auth-0.1.0.tar.gz
  • Upload date:
  • Size: 61.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.13.1

File hashes

Hashes for agentidentity_auth-0.1.0.tar.gz
Algorithm Hash digest
SHA256 dfc5e19246bea3760ddaa12f6e4e8770ed2df84026059eb1f61b0e5f8bbef306
MD5 911faa77193a7893d7a727d669912b2a
BLAKE2b-256 9d2878a7e484ad130623bc22d92be500f0cfdc50c1e2c2f9e4ac0e26c0ae92d8

See more details on using hashes here.

File details

Details for the file agentidentity_auth-0.1.0-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for agentidentity_auth-0.1.0-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 c3e2c63d65b2cae69751751d332e23c844b3c02a375fd7fc508aa91ca3ac8608
MD5 62588dc1abf968c07f1977cf763010d6
BLAKE2b-256 0f40eb93d79e8aa9dd200315df3550d5b0fd4988777e9eb69dc1ae6a6bd80b0c

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