npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

agents-chain

v0.0.59

Published

Lightweight identity, auth, and audit layer for AI agent SDKs (OpenAI, Anthropic)

Readme

agents-chain

v0.0.58 — Zero-dependency security layer for AI agent systems. Ed25519 identity, JWT auth, constraint enforcement, encrypted audit, human-in-the-loop access requests, constraint-aware agent flows, and end-to-end agent session tracing.

npm License: MIT

Full documentation


Install

npm install agents-chain

Requires Node.js 18+. Ships ESM + CommonJS.

What It Does

  • Host + Agent identity — Ed25519 keypairs with JWK thumbprints as stable IDs
  • 11-step JWT verification — signature, replay protection, delegation chain, grant + constraint enforcement
  • Grant constraints — field-level rules: max, min, in, not_in, exact equality
  • Access requests — denied calls suspend and wait for human approval out-of-band (HMAC-verified, 4 scopes)
  • Constraint-aware mode — returns structured violation envelopes so AI agents can reason about permissions and explicitly request approval
  • Encrypted audit log — AES-256-GCM ring buffer with auth overhead tracking, access request lifecycle events
  • Session tracingopenTrace() / closeTrace() groups all capability and LLM calls into a single TraceRun with token counts, model names, tool calls, and per-span results
  • Zero dependencies — everything defaults to in-memory, external systems are adapter-injected

Quick Start

import { AppChain, isChainAuthError } from 'agents-chain';

const chain = await AppChain.create({
  providerName: 'billing-service',
  issuer: 'https://billing.example.com',
  capabilities: [{
    name: 'createInvoice',
    description: 'Create an invoice',
    inputSchema: {
      type: 'object',
      required: ['customerId', 'amount'],
      properties: {
        customerId: { type: 'string' },
        amount: { type: 'number' },
      },
    },
    outputSchema: { type: 'object' },
    execute: async (args, ctx) => {
      return { invoiceId: 'inv_001', amount: args.amount };
    },
  }],
});

const grants = [{
  capability: 'createInvoice',
  status: 'active' as const,
  constraints: { amount: { max: 5000 } },
  expiresAt: Date.now() + 86_400_000,
}];

const secured = chain.wrap({}, grants);

await secured.createInvoice({ customerId: 'c1', amount: 500 });  // ✅
await secured.createInvoice({ customerId: 'c1', amount: 99999 }); // ❌ constraint_violated

Constraint-Aware Mode

When constraintAware is enabled, capability calls return structured ConstraintAwareResult envelopes instead of throwing errors. This lets AI agents understand violations and decide whether to request human approval.

const chain = await AppChain.create({
  // ...capabilities, accessRequests config...
  constraintAware: true,
});

const secured = chain.wrap(service, grants);

// Allowed call — returns success envelope
const result = await secured.sendSms({ to: '+1234', message: 'Hello' });
// { success: true, result: {...}, permission: "not_required", capability: "sendSms" }

// Violation — returns structured error instead of throwing
const denied = await secured.sendSms({ to: '+9999', message: 'Hello' });
// {
//   success: false,
//   permission: "constraint_violated",
//   violations: [{ field: "to", constraint: "in", expected: ["+1234"], actual: "+9999", message: "..." }],
//   guidance: "Call request_permission to request human approval",
//   capability: "sendSms",
//   activeConstraints: { to: { in: ["+1234"] } }
// }

Two-Step Agent-Driven Permission Flow

With constraintAware: true and accessRequests configured, a built-in request_permission capability is auto-registered. The agent explicitly decides when to request human approval:

Step 1: Agent calls sendSms(+9999)
        → Returns structured violation (no suspension, no throw)

Step 2: Agent calls request_permission({ capability: "sendSms", args: {...}, reason: "..." })
        → Suspends until human approves/denies
        → Returns: { success: true, permission: "approved", result: {...} }
           OR:    { success: false, permission: "denied", reason: "..." }

The agent receives a constraint context string via chain.getConstraintContext(grants) that can be injected into its system prompt.

Access Requests

When accessRequests is configured, denied calls suspend instead of throwing. The call blocks until a human approves or denies via an HMAC-verified code:

const chain = await AppChain.create({
  // ...
  accessRequests: {
    approvalSecret: process.env.APPROVAL_SECRET,
    requestTTLMs: 5 * 60 * 1000,
    notifier: {
      async notify(request) {
        console.log(`Code: ${request.verificationCode}`);
      },
    },
  },
});

// Approve with 4 scopes: call, value, capability, global
chain.approve({ requestId, code, scope: 'value' });

Read more about access requests

Audit Trail

The audit log captures the full lifecycle of capability calls, including access request events:

| Result | Description | |--------|-------------| | success | Capability executed successfully | | denied | Call rejected by auth or constraints | | error | Capability threw during execution | | access_requested | Agent requested human approval (call suspended) | | access_approved | Human approved the access request | | access_denied | Human denied the access request |

Export audit entries to external systems via HttpAuditExporter or implement your own AuditExporter.

Session Tracing

Track a complete agent session — every capability call, every LLM invocation, token counts, and tool calls — as a single exportable TraceRun:

import { AppChain, HttpTraceExporter } from 'agents-chain';

const chain = await AppChain.create({
  // ...
  traceExporter: new HttpTraceExporter({
    endpoint: 'https://gateway.melduo.com/traces',
    apiKey: process.env.MELDUO_API_KEY,
  }),
});

// Open a trace at session start
const traceId = chain.openTrace();

// Pass traceId into wrap() and openai()/anthropic() to group spans
const secured = chain.wrap(myService, grants, traceId);
const openai = chain.openai(new OpenAI({ apiKey: '...' }), traceId);

await secured.sendEmail({ to: '[email protected]', subject: 'Hello' });
await openai.chat.completions.create({ model: 'gpt-4o', messages: [...] });

// Close the trace — assembles the TraceRun and exports it
const run = await chain.closeTrace(traceId, 'success');
// run.summary.totalTokens   → 1240
// run.summary.modelsUsed    → ["gpt-4o"]
// run.spans                 → [{ capability, result, durationMs, modelMetadata }, ...]

For custom LLM providers (Google, Cohere, etc.), implement and register a ModelMetadataExtractor.

Documentation

| Section | Description | |---------|-------------| | Getting Started | Installation, quick start, how it works | | Core Concepts | Host & Agent, Capabilities, Grants, Verification, Audit | | Tracing & Observability | Session traces, token counts, model extractors, exporters | | Access Requests | Suspend/resume, approval scopes, security model | | Examples | Basic service, SMS gateway, access request flow | | API Reference | AppChainConfig, types, error codes | | Architecture | Module map, data flows, internals |

Sponsored by

Sponsored by Melduo

License

MIT — brianmwangidev