Observed since 20 Oct, 18:25 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Production-grade agent identity for AI systems. Ed25519 signed Agent Cards. Implements ACRF-01 defense pattern.
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.
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.
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.
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.
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
The private card file contains the Ed25519 private key. Treat it like any other production secret:
What NOT to do:
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.
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.
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.
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.
LangChain, CrewAI, AutoGen, MCP-based systems, custom agents. If your agents send messages to each other, you can use this library.
Ravi Karthick Sankara Narayanan, Kanna Sekar
Apache 2.0
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.1.0 | 5 May 2026 | 1 |
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 18:25 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:e81bda3b419c1f97e1ea68b9b803cf3467ebc8d9ffb30476eebd093ddcca26a3