View on GitHub →
← Back to Home

Agent Identity with JavaScript

An interactive guide to AgentPin — issue and verify agent credentials in Node.js.

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 Credential Expired / Revoked
{
  "valid": true,
  "agent_id": "urn:agentpin:example.com:my-agent",
  "issuer": "example.com",
  "capabilities": ["read:data", "write:reports"],
  "key_pinning": { "status": "first_use" }
}