Production-grade agent identity for AI systems. Ed25519 signed Agent Cards. Implements ACRF-01 defense pattern.
Project description
acrf-identity
Production-grade agent identity for AI systems. Implements the ACRF-01 (Implicit Trust Between Agents) defense pattern.
Part of the ACRF framework: https://github.com/kannasekar-alt/ACRF PyPI: https://pypi.org/project/acrf-identity/ Presented at RSA Conference 2026.
Try it in your environment right now
No Docker. No setup. Just Python 3.10+.
Step 1 - Install:
pip install acrf-identity
Step 2 - Generate identity for each agent (one-time setup):
from acrf_identity import AgentCard
card = AgentCard.generate(
agent_name="PricingAgent",
organization="acme-corp",
metadata={"version": "1.0", "team": "trading"}
)
card.save("pricing_private.json") # KEEP SECRET
card.public_only().save("pricing_public.json") # safe to share
Step 3 - Sign every outgoing message:
from acrf_identity import AgentCard, MessageEnvelope
card = AgentCard.load("pricing_private.json")
envelope = MessageEnvelope.create(
payload={"action": "book_flight", "amount": 500},
sender=card,
recipient="BookingAgent"
)
send_to_other_agent(envelope.to_json())
Step 4 - Verify every incoming message:
from acrf_identity import TrustStore, MessageEnvelope
trust_store = TrustStore.load("trusted_agents.json")
envelope = MessageEnvelope.from_json(received_json)
payload = trust_store.verify(envelope) # raises if invalid
If the envelope signature is invalid, the sender is unknown, the message is expired, or the nonce was already seen, verify() raises an AgentIdentityError subclass. Your application fails closed.
The problem this solves
In a multi-agent system, every message from one agent to another is a trust decision. If your booking agent receives an instruction to book a $5000 flight, how does it know that instruction came from the legitimate pricing agent and not an attacker who compromised the network?
Without cryptographic identity - it does not.
This is ACRF-01: implicit trust between agents.
acrf-identity gives every agent a verifiable cryptographic identity using Ed25519 signatures. Every message is signed by the sender and verified by the recipient before any action is taken.
Security features built in
This is not a toy library. It includes the things you need for production:
Ed25519 signatures Industry-standard, fast, and secure. Used by SSH, TLS, and major cryptocurrencies.
Replay attack protection - timestamps Every envelope contains a timestamp. Messages older than 5 minutes are rejected even if the signature is valid. Configurable via max_message_age.
Replay attack protection - nonces Every envelope has a unique nonce. The trust store remembers seen nonces and rejects duplicates. Even if an attacker captures a valid envelope, they cannot replay it.
Agent revocation Compromised agents can be revoked instantly. Revoked agents fail every verification regardless of signature validity.
Key rotation with grace period Agents can rotate their keys without losing identity. The trust store keeps the old key in its index for the grace period so in-flight messages still verify.
Audit trail Every verification attempt produces an audit record (success or failure) with sender, recipient, timestamp, and outcome. Use it for security monitoring and compliance.
CLI
Set the trust store path once:
export ACRF_TRUST_STORE=/etc/acrf/trusted_agents.json
Generate a new agent identity:
acrf-identity generate PricingAgent --organization acme-corp
This creates two files:
PricingAgent_private.json <-- KEEP SECRET
PricingAgent_public.json <-- share with verifiers
Add an agent to the trust store:
acrf-identity trust add PricingAgent_public.json
Revoke an agent:
acrf-identity trust revoke CompromisedAgent
Rotate the key for an existing agent:
acrf-identity trust rotate PricingAgent_public_v2.json
List trusted and revoked agents:
acrf-identity trust list
Verify a message envelope:
acrf-identity verify message_envelope.json
How it works
- Each agent generates an Ed25519 keypair (one time)
- The public key, agent name, organization, and metadata form an Agent Card
- Public Agent Cards are added to a TrustStore on every recipient agent
- When sending a message, the sender wraps it in a MessageEnvelope
- The envelope contains the payload, sender ID, recipient, timestamp, nonce
- The envelope is signed with the senders private key (Ed25519)
- The recipient looks up the senders public card in its TrustStore
- The recipient verifies signature, timestamp, nonce, and revocation status
- If all checks pass, the payload is accepted; otherwise an exception is raised
What goes in the private card storage
The private card file contains the Ed25519 private key. Treat it like any other production secret:
- Mount via Kubernetes secrets at runtime
- Read from AWS Secrets Manager / Azure Key Vault / GCP Secret Manager
- Read from HashiCorp Vault
- Use file permissions 0600 if storing on disk
What NOT to do:
- Commit private cards to source control
- Bake them into Docker images
- Share them between agents (each agent gets its own card)
Trust store deployment patterns
Centralized trust store One JSON file maintained by a security team, distributed to all agents. Updates pushed via configuration management.
Per-agent trust stores Each agent has its own trust store containing only the agents it expects to communicate with. Smaller blast radius if a single agent is compromised.
Dynamic trust store Agents fetch trusted cards from a registry at startup. Useful for very large deployments. The registry itself becomes a trust anchor.
Real-world use
Wrap your messaging layer with two helper functions:
from acrf_identity import AgentCard, TrustStore, MessageEnvelope
import os
MY_CARD = AgentCard.load(os.environ["AGENT_PRIVATE_CARD"])
TRUST = TrustStore.load(os.environ["ACRF_TRUST_STORE"])
def send(payload, recipient):
envelope = MessageEnvelope.create(payload, MY_CARD, recipient)
return envelope.to_json()
def receive(envelope_json):
envelope = MessageEnvelope.from_json(envelope_json)
return TRUST.verify(envelope) # raises on any failure
That is it. Every agent-to-agent message is now cryptographically verified with replay protection and revocation support.
ACRF-01 control objectives addressed
IT-1 Every agent message is cryptographically authenticated before processing
IT-2 Agent identity verified against a trusted Agent Card registry
IT-3 Rejection of unverified messages logged with full audit context
Out of scope (your infrastructure):
IT-4 Warrant delegation with scoped authority per request
Per-request warrant delegation is more than what this library provides; combine acrf-identity with acrf-tokens for that pattern.
What this library does NOT do
- It does not encrypt the message payload (use TLS or application-level encryption)
- It does not authenticate humans (use OAuth/SSO for that)
- It does not enforce authorization policies (it answers "who is this?", not "what may they do?")
It only ensures that a message claiming to be from Agent X is actually from Agent X, has not been tampered with, and is not a replay. That is the ACRF-01 defense pattern.
Works with any Python AI agent framework
LangChain, CrewAI, AutoGen, MCP-based systems, custom agents. If your agents send messages to each other, you can use this library.
Authors
Ravi Karthick Sankara Narayanan, Kanna Sekar
License
Apache 2.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file acrf_identity-0.1.0.tar.gz.
File metadata
- Download URL: acrf_identity-0.1.0.tar.gz
- Upload date:
- Size: 18.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a241ab7f56007824dfebc30df1c17d00cdbc32c621cdd07c9d23972c5c3b6f4a
|
|
| MD5 |
b036f93b0a532ab7c379ecf81cf28cf1
|
|
| BLAKE2b-256 |
c40597cf2bf76c945554369743a9502d67e9914a68603a2b4f00bc309abf10af
|
File details
Details for the file acrf_identity-0.1.0-py3-none-any.whl.
File metadata
- Download URL: acrf_identity-0.1.0-py3-none-any.whl
- Upload date:
- Size: 15.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0613631e61d30d66bac643f70540ed0b82f5a09e03520f774467511bb13a3b6e
|
|
| MD5 |
efaecf50a8f0bc88ac27c12cb7bd8b2f
|
|
| BLAKE2b-256 |
976c3d39d44edcb71bda9271e5ade29dca28b369a69e99bab1681e0c658ea9e3
|