The Problem: AI Agent Impersonation
As AI agents become more autonomous and interact with external services, a critical question arises: how do you know which agent you're talking to?
Without cryptographic identity, any agent can claim to be any other agent. A malicious actor could deploy an agent that impersonates a trusted service, exfiltrating data or performing unauthorized actions.
AgentPin solves this with domain-anchored cryptographic credentials — ES256 JWTs tied to discoverable public keys, with capability scoping, delegation chains, and TOFU key pinning.
Step 1: Install
npm install agentpin
Step 2: Generate Keys & Build Discovery
Generate an ECDSA P-256 keypair and create a discovery document.
import {
generateKeyPair,
generateKeyId,
buildDiscoveryDocument,
pemToJwk,
} from 'agentpin';
// Generate keypair
const { privateKeyPem, publicKeyPem } = generateKeyPair();
const kid = generateKeyId(publicKeyPem);
// Create JWK for discovery
const jwk = pemToJwk(publicKeyPem, kid);
// Build discovery document
const discovery = buildDiscoveryDocument(
'example.com', // entity domain
'maker', // entity type
[jwk], // public keys
[{
agent_id: 'urn:agentpin:example.com:my-agent',
name: 'My Agent',
capabilities: ['read:data', 'write:reports'],
status: 'active',
}],
2, // max delegation depth
new Date().toISOString()
);
console.log(JSON.stringify(discovery, null, 2));
Step 3: Issue a Credential
Issue a signed JWT credential for your agent.
import { issueCredential, Capability } from 'agentpin';
const credential = issueCredential(
privateKeyPem,
kid, // key ID
'example.com', // issuer
'urn:agentpin:example.com:my-agent', // agent ID
'verifier.com', // audience
[new Capability('read:data'),
new Capability('write:reports')], // capabilities
null, // constraints
null, // delegation chain
3600 // TTL in seconds
);
console.log('Credential JWT:', credential);
Step 4: Verify a Credential
Verify a credential offline (with a local discovery document) or online (auto-fetching from the issuer's domain).
import {
verifyCredentialOffline,
verifyCredential,
KeyPinStore,
} from 'agentpin';
const pinStore = new KeyPinStore();
// Offline verification (with local discovery doc)
const result = verifyCredentialOffline(
credential,
discovery, // discovery document
null, // revocation document (optional)
pinStore,
'verifier.com', // expected audience
{ clockSkewSecs: 60, maxTtlSecs: 86400 }
);
if (result.valid) {
console.log('Agent:', result.agent_id);
console.log('Issuer:', result.issuer);
console.log('Capabilities:', result.capabilities);
console.log('Key pinning:', result.key_pinning);
} else {
console.error('Failed:', result.error_code, result.error_message);
}
// Online verification (auto-fetches discovery)
const onlineResult = await verifyCredential(
credential,
pinStore,
'verifier.com',
{ clockSkewSecs: 60, maxTtlSecs: 86400 }
);
Verification Result
{
"valid": true,
"agent_id": "urn:agentpin:example.com:my-agent",
"issuer": "example.com",
"capabilities": ["read:data", "write:reports"],
"key_pinning": { "status": "first_use" }
}