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

@authora/sdk

v0.4.3

Published

Official TypeScript/JavaScript SDK for the Authora platform

Readme

@authora/sdk

npm version License: MIT

Authorization for AI agents -- identity, permissions, and delegation management.

Quick Start

// npm install @authora/sdk
import { AuthoraClient } from '@authora/sdk';

const authora = new AuthoraClient({ apiKey: 'authora_live_...' });

// Create an agent
const { agent } = await authora.agents.create({
  workspaceId: 'ws_...', name: 'my-agent', createdBy: 'usr_...',
});

// Check a permission
const result = await authora.permissions.check({
  agentId: agent.id, resource: 'files:reports/*', action: 'read',
});
console.log(result.allowed ? 'Access granted' : 'Denied');

Table of Contents

Installation

npm install @authora/sdk
# or
pnpm add @authora/sdk
# or
yarn add @authora/sdk

Getting Credentials

Automatic (IDE agents): If you use Claude Code, Cursor, or OpenCode, credentials are created automatically on first run via browser sign-in. See self-onboarding instructions.

Manual: Sign up at authora.dev/get-started, then create an API key in the dashboard.

Environment variables (Docker/CI): Set AUTHORA_API_KEY, AUTHORA_AGENT_ID, AUTHORA_ORG_ID, AUTHORA_WORKSPACE_ID.

Features

  • Zero runtime dependencies -- uses native fetch
  • Full TypeScript support with strict types and JSDoc
  • ES modules + CommonJS dual output
  • Works in Node.js 18+ and modern browsers

Configuration

| Option | Type | Default | Description | | --------- | ------------------------ | ------------------------------------ | -------------------------------- | | apiKey | string | (required) | API key for Bearer authentication | | baseUrl | string | https://api.authora.dev/api/v1 | Base URL for the API | | timeout | number | 30000 | Request timeout in milliseconds | | headers | Record<string, string> | {} | Custom headers for every request |

Edge Endpoints

For high-availability scenarios, Authora provides an edge proxy at https://edge.authora.dev powered by Cloudflare Workers. Agent identity verification, JWT validation, and public key lookups are served from globally distributed edge caches with 24-hour survivability if the origin is unreachable. The edge proxy runs in parallel with the primary API -- no client changes required.


Resources

Organizations

// Create an organization
const org = await authora.organizations.create({
  name: 'Acme Corp',
  slug: 'acme-corp',
});

// Get an organization
const org = await authora.organizations.get('org_123');

// List organizations
const { items, total } = await authora.organizations.list({ page: 1, limit: 20 });

Workspaces

// Create a workspace
const ws = await authora.workspaces.create({
  organizationId: 'org_123',
  name: 'Production',
  slug: 'production',
});

// Get a workspace
const ws = await authora.workspaces.get('ws_456');

// List workspaces in an organization
const { items } = await authora.workspaces.list({
  organizationId: 'org_123',
  page: 1,
  limit: 50,
});

Agents

// Create an agent
const agent = await authora.agents.create({
  workspaceId: 'ws_456',
  name: 'data-processor',
  description: 'Processes incoming data files',
  createdBy: 'user_789',
  tags: ['etl', 'production'],
  framework: 'langchain',
  modelProvider: 'openai',
  modelId: 'gpt-4',
});

// List agents with filters
const { items, total } = await authora.agents.list({
  workspaceId: 'ws_456',
  status: 'ACTIVE',
  page: 1,
  limit: 25,
});

// Get a single agent
const agent = await authora.agents.get('agt_abc');

// Verify agent identity (public, no auth required)
const verification = await authora.agents.verify('agt_abc');
if (verification.valid) {
  console.log('Agent is valid');
}

// Activate a pending agent
const activated = await authora.agents.activate('agt_abc', {
  publicKey: 'ssh-ed25519 AAAA...',
});

// Suspend an agent
const suspended = await authora.agents.suspend('agt_abc');

// Revoke an agent permanently
const revoked = await authora.agents.revoke('agt_abc');

// Rotate an agent's key
const rotated = await authora.agents.rotateKey('agt_abc', {
  publicKey: 'ssh-ed25519 BBBB...',
});

Roles

// Create a role
const role = await authora.roles.create({
  workspaceId: 'ws_456',
  name: 'data-reader',
  description: 'Read-only access to data resources',
  permissions: ['data:read', 'metadata:read'],
  denyPermissions: ['data:delete'],
  stage: 'production',
  maxSessionDuration: 3600,
});

// List roles
const { items } = await authora.roles.list({ workspaceId: 'ws_456' });

// Get a role
const role = await authora.roles.get('role_123');

// Update a role
const updated = await authora.roles.update('role_123', {
  permissions: ['data:read', 'data:write', 'metadata:read'],
});

// Delete a role
await authora.roles.delete('role_123');

// Assign a role to an agent
const assignment = await authora.roles.assign('agt_abc', {
  roleId: 'role_123',
  grantedBy: 'user_789',
  expiresAt: '2025-12-31T23:59:59Z',
});

// Remove a role from an agent
await authora.roles.unassign('agt_abc', 'role_123');

// List roles assigned to an agent
const assignments = await authora.roles.listAgentRoles('agt_abc');

Permissions

// Check a single permission
const result = await authora.permissions.check({
  agentId: 'agt_abc',
  resource: 'files:reports/*',
  action: 'read',
  context: { environment: 'production' },
});

if (result.allowed) {
  console.log('Access granted');
}

// Batch check multiple permissions
const batch = await authora.permissions.checkBatch({
  agentId: 'agt_abc',
  checks: [
    { resource: 'files:reports/*', action: 'read' },
    { resource: 'files:reports/*', action: 'write' },
    { resource: 'config:*', action: 'admin' },
  ],
});

batch.results.forEach((r, i) => {
  console.log(`Check ${i}: ${r.allowed ? 'allowed' : 'denied'}`);
});

// Get effective permissions for an agent
const effective = await authora.permissions.getEffective('agt_abc');
console.log('Allowed:', effective.permissions);
console.log('Denied:', effective.denyPermissions);

Delegations

// Create a delegation
const delegation = await authora.delegations.create({
  workspaceId: 'ws_456',
  issuerAgentId: 'agt_abc',
  targetAgentId: 'agt_def',
  permissions: ['files:read', 'files:list'],
  constraints: {
    expiresAt: new Date(Date.now() + 3600000).toISOString(),
    maxDepth: 2,
  },
});

// Get a delegation
const delegation = await authora.delegations.get('del_123');

// Revoke a delegation
const revoked = await authora.delegations.revoke('del_123');

// Verify a delegation is still valid
const verification = await authora.delegations.verify({
  delegationId: 'del_123',
});

// List all delegations (with optional workspace filter)
const { items } = await authora.delegations.list({
  workspaceId: 'ws_456',
  page: 1,
  limit: 20,
});

// List delegations for a specific agent
const agentDelegations = await authora.delegations.listByAgent('agt_abc', {
  direction: 'issued',
  page: 1,
  limit: 50,
});

Policies

// Create a policy
const policy = await authora.policies.create({
  workspaceId: 'ws_456',
  name: 'allow-data-read',
  description: 'Allow all agents to read data resources',
  effect: 'ALLOW',
  principals: { roles: ['data-reader'], agents: [], workspaces: [] },
  resources: ['data:*'],
  actions: ['read', 'list'],
  conditions: { environment: { equals: 'production' } },
  priority: 10,
  enabled: true,
});

// List policies
const { items } = await authora.policies.list({ workspaceId: 'ws_456' });

// Update a policy
const updated = await authora.policies.update('pol_123', {
  enabled: false,
});

// Delete a policy
await authora.policies.delete('pol_123');

// Simulate a policy evaluation (dry-run)
const simulation = await authora.policies.simulate({
  workspaceId: 'ws_456',
  agentId: 'agt_abc',
  resource: 'data:users',
  action: 'read',
});

console.log(`Would be ${simulation.allowed ? 'allowed' : 'denied'}`);
console.log('Matched policies:', simulation.matchedPolicies);

// Evaluate policies (live)
const evaluation = await authora.policies.evaluate({
  workspaceId: 'ws_456',
  agentId: 'agt_abc',
  resource: 'data:users',
  action: 'write',
});

// Attach a policy to an agent
const attachment = await authora.policies.attachToTarget({
  policyId: 'pol_123',
  targetType: 'agent',
  targetId: 'agt_abc',
});

// Attach a policy to an MCP server
await authora.policies.attachToTarget({
  policyId: 'pol_123',
  targetType: 'mcp_server',
  targetId: 'mcp_xyz',
});

// Add permissions to an existing attached policy (avoids creating new policies)
const updated = await authora.policies.addPermission({
  policyId: 'pol_123',
  resources: ['mcp:server1:tool.new_tool'],
  actions: ['execute'],
});

// Remove permissions from a policy
await authora.policies.removePermission({
  policyId: 'pol_123',
  resources: ['mcp:server1:tool.old_tool'],
  actions: ['execute'],
});

// List all policies attached to an agent
const agentPolicies = await authora.policies.listAttachments({
  targetType: 'agent',
  targetId: 'agt_abc',
});

// List all targets a policy is attached to
const targets = await authora.policies.listPolicyTargets('pol_123');

// Detach a policy
await authora.policies.detachFromTarget({
  policyId: 'pol_123',
  targetType: 'agent',
  targetId: 'agt_abc',
});

MCP Servers

// Register an MCP server
const server = await authora.mcp.register({
  workspaceId: 'ws_456',
  name: 'code-tools',
  description: 'Code analysis and generation tools',
  url: 'https://mcp.example.com',
  transport: 'sse',
  version: '1.0.0',
  connectionTimeout: 5000,
  maxRetries: 3,
});

// List MCP servers
const { items } = await authora.mcp.listServers({ workspaceId: 'ws_456' });

// Get a server
const server = await authora.mcp.getServer('srv_123');

// Update a server
const updated = await authora.mcp.updateServer('srv_123', {
  connectionTimeout: 10000,
});

// List tools on a server
const tools = await authora.mcp.listTools('srv_123');

// Register a tool
const tool = await authora.mcp.registerTool('srv_123', {
  name: 'analyze-code',
  description: 'Analyzes code for quality issues',
  inputSchema: {
    type: 'object',
    properties: {
      code: { type: 'string' },
      language: { type: 'string' },
    },
    required: ['code'],
  },
});

// Proxy a JSON-RPC request to an MCP server
const response = await authora.mcp.proxy({
  jsonrpc: '2.0',
  method: 'tools/call',
  params: { name: 'analyze-code', arguments: { code: 'const x = 1;' } },
  id: 1,
});

Audit

// List audit events with filters
const { items, total } = await authora.audit.listEvents({
  workspaceId: 'ws_456',
  agentId: 'agt_abc',
  type: 'permission.check',
  dateFrom: '2025-01-01T00:00:00Z',
  dateTo: '2025-01-31T23:59:59Z',
  result: 'allowed',
  page: 1,
  limit: 100,
});

// Get a single event
const event = await authora.audit.getEvent('evt_123');

// Generate an audit report
const report = await authora.audit.generateReport({
  orgId: 'org_123',
  dateFrom: '2025-01-01',
  dateTo: '2025-01-31',
});

// Get audit metrics
const metrics = await authora.audit.getMetrics({
  orgId: 'org_123',
  workspaceId: 'ws_456',
  dateFrom: '2025-01-01',
  dateTo: '2025-01-31',
});

console.log('Total events:', metrics.totalEvents);
console.log('By type:', metrics.eventsByType);

Notifications

// List notifications
const notifications = await authora.notifications.list({
  organizationId: 'org_123',
  userId: 'user_789',
  unreadOnly: true,
  limit: 20,
});

// Get unread count
const { count } = await authora.notifications.unreadCount({
  organizationId: 'org_123',
  userId: 'user_789',
});

// Mark a single notification as read
const notification = await authora.notifications.markRead('notif_123');

// Mark all notifications as read
await authora.notifications.markAllRead({
  organizationId: 'org_123',
  userId: 'user_789',
});

Webhooks

// Create a webhook
const webhook = await authora.webhooks.create({
  organizationId: 'org_123',
  url: 'https://example.com/hooks/authora',
  eventTypes: ['agent.created', 'agent.suspended', 'permission.denied'],
  secret: 'whsec_...',
});

// List webhooks
const webhooks = await authora.webhooks.list({ organizationId: 'org_123' });

// Update a webhook
const updated = await authora.webhooks.update('wh_123', {
  eventTypes: ['agent.created', 'agent.suspended'],
  enabled: false,
});

// Delete a webhook
await authora.webhooks.delete('wh_123');

Alerts

// Create an alert
const alert = await authora.alerts.create({
  organizationId: 'org_123',
  name: 'high-denial-rate',
  eventTypes: ['permission.denied'],
  conditions: { threshold: 100, windowMinutes: 5 },
  channels: [
    { type: 'email', address: '[email protected]' },
    { type: 'slack', webhookUrl: 'https://hooks.slack.com/...' },
  ],
});

// List alerts
const alerts = await authora.alerts.list({ organizationId: 'org_123' });

// Update an alert
const updated = await authora.alerts.update('alert_123', {
  conditions: { threshold: 50, windowMinutes: 10 },
});

// Delete an alert
await authora.alerts.delete('alert_123');

Approvals

// Create an approval challenge
const challenge = await authora.approvals.create({
  organizationId: 'org_123',
  workspaceId: 'ws_456',
  agentId: 'agt_abc',
  resource: 'production:database',
  action: 'delete',
  challengeType: 'tool_call',
  toolName: 'drop_table',
});

console.log(challenge.status);    // 'PENDING'
console.log(challenge.riskLevel); // 'HIGH'

// Approve or deny
const decided = await authora.approvals.decide(challenge.id, {
  action: 'approve',
  scope: 'once',
  note: 'One-time approval for migration',
  source: 'dashboard',
});

// Get approval stats
const stats = await authora.approvals.stats();
console.log(stats.pending, stats.approvedToday);

// List approval challenges
const { items } = await authora.approvals.list({
  status: 'PENDING',
  page: 1,
  limit: 20,
});

// Escalation rules
const rule = await authora.approvals.createEscalationRule({
  name: 'high-risk-escalation',
  riskLevels: ['HIGH', 'CRITICAL'],
  steps: [{
    delaySeconds: 300,
    notifyUserIds: ['usr_admin1'],
    channels: ['slack_channel', 'dashboard'],
  }],
});

// Approval webhooks
const webhook = await authora.approvals.createWebhook({
  name: 'my-webhook',
  url: 'https://example.com/hooks/approval',
  secret: 'whsec_...',
  eventTypes: ['challenge.created', 'challenge.decided'],
});

Credits

// Get credit balance
const balance = await authora.credits.balance();
console.log(balance.balance);
console.log(balance.lifetimePurchased);
console.log(balance.lifetimeConsumed);

// List credit transactions
const { items } = await authora.credits.transactions({
  type: 'consume',
  limit: 20,
});

// Purchase credits
const { url } = await authora.credits.checkout('starter');
// Redirect user to url for payment

User Delegations (RFC 8693)

// Issue a token for a user delegation grant
const token = await authora.userDelegations.issueToken('grant_123', {
  agentFullId: 'org_abc/agt_xyz',
  audience: 'mcp-server-123',
  lifetimeSeconds: 3600,
});

console.log(token.token);     // EdDSA JWT
console.log(token.expiresAt); // ISO 8601

// Verify a user delegation token
const verification = await authora.userDelegations.verifyToken(token.token);
console.log(verification.valid);     // true
console.log(verification.scopes);    // ['files:read', 'calendar:read']

// List active grants for a user
const grants = await authora.userDelegations.listByUser('user_123', {
  status: 'ACTIVE',
});

// Revoke a grant
await authora.userDelegations.revoke('grant_123', {
  revokedBy: 'user_123',
  reason: 'No longer needed',
});

Agent Groups

// Create a group and add members
const group = await authora.agentGroups.create({
  workspaceId: 'ws_456', name: 'billing-agents',
});
await authora.agentGroups.addMembers(group.id, ['agt_abc', 'agt_def']);

// List members and groups
const members = await authora.agentGroups.listMembers(group.id);
const groups = await authora.agents.listGroups('agt_abc');

// Bulk assign role by tag
await authora.agents.bulkAssignRole({ roleId: 'role_123', tags: ['production'] });

// Target policies by group or tag
await authora.policies.create({
  workspaceId: 'ws_456', name: 'billing-access', effect: 'ALLOW',
  principals: { agentGroups: ['grp_abc'], agentTags: ['billing'] },
  resources: ['billing:*'], actions: ['read', 'write'],
});

API Keys

// Create an API key
const apiKey = await authora.apiKeys.create({
  organizationId: 'org_123',
  name: 'ci-pipeline',
  scopes: ['agents:read', 'agents:write', 'permissions:check'],
  createdBy: 'user_789',
  expiresInDays: 90,
});

// The full key is only available at creation time
console.log('Key:', apiKey.key);

// List API keys
const keys = await authora.apiKeys.list({ organizationId: 'org_123' });

// Revoke an API key
await authora.apiKeys.revoke('key_123');

Error Handling

All API errors are thrown as typed exceptions that extend AuthoraError:

import {
  AuthoraClient,
  AuthoraError,
  AuthenticationError,
  AuthorizationError,
  NotFoundError,
  RateLimitError,
  NetworkError,
  TimeoutError,
} from '@authora/sdk';

const authora = new AuthoraClient({ apiKey: 'authora_live_...' });

try {
  await authora.agents.get('agt_nonexistent');
} catch (err) {
  if (err instanceof NotFoundError) {
    console.error('Agent not found:', err.message);
  } else if (err instanceof AuthenticationError) {
    console.error('Bad API key:', err.message);
  } else if (err instanceof AuthorizationError) {
    console.error('Insufficient permissions:', err.message);
  } else if (err instanceof RateLimitError) {
    console.error('Rate limited. Retry after:', err.retryAfter, 'seconds');
  } else if (err instanceof TimeoutError) {
    console.error('Request timed out');
  } else if (err instanceof NetworkError) {
    console.error('Network issue:', err.message);
  } else if (err instanceof AuthoraError) {
    console.error(`API error ${err.statusCode}: ${err.message}`);
    console.error('Code:', err.code);
    console.error('Details:', err.details);
  }
}

Error Classes

| Class | HTTP Status | Description | | --------------------- | ----------- | ------------------------------------ | | AuthoraError | any | Base class for all API errors | | AuthenticationError | 401 | Invalid or missing API key | | AuthorizationError | 403 | Insufficient permissions | | NotFoundError | 404 | Requested resource does not exist | | RateLimitError | 429 | Too many requests; includes retryAfter | | TimeoutError | 408 | Request exceeded the timeout | | NetworkError | 0 | Network/connectivity failure |


Agent Runtime

The AuthoraAgent class provides a full agent runtime with Ed25519 signed requests, client-side permission caching, delegation, and MCP tool calls.

import { AuthoraClient, AuthoraAgent, generateKeyPair } from '@authora/sdk';

const client = new AuthoraClient({ apiKey: 'authora_live_...' });

// Create + activate an agent (generates keypair, calls create + activate)
const { agent, keyPair } = await client.createAgent({
  workspaceId: 'ws_456',
  name: 'data-processor',
  createdBy: 'admin',
});

// Load the agent runtime
const runtime = client.loadAgent({
  agentId: agent.id,
  privateKey: keyPair.privateKey,
});

// All requests are Ed25519-signed automatically
const profile = await runtime.getProfile();
const doc = await runtime.getIdentityDocument();

// Server-side permission check
const { allowed, reason } = await runtime.checkPermission('files:read', 'read');

// Batch permission check
const results = await runtime.checkPermissions([
  { resource: 'files:read', action: 'read' },
  { resource: 'files:delete', action: 'delete' },
]);

// Client-side cached permission check (deny-first, 5-minute TTL)
if (await runtime.hasPermission('mcp:server1:tool.query')) {
  // MCP tool call through the gateway
  const result = await runtime.callTool({
    mcpServerId: 'mcp_server1',
    toolName: 'query',
    arguments: { sql: 'SELECT 1' },
  });
}

// Delegate permissions to another agent
const delegation = await runtime.delegate({
  targetAgentId: 'agent_...',
  permissions: ['files:read'],
  constraints: {
    expiresAt: new Date(Date.now() + 3600000).toISOString(),
    singleUse: true,
  },
});

// Load a delegated agent
const delegated = client.loadDelegatedAgent({
  agentId: 'agent_target',
  privateKey: targetKeyPair.privateKey,
  delegationToken: delegation.id,
});

// Key rotation (generates new keypair, registers with server)
const { agent: updated, keyPair: newKeyPair } = await runtime.rotateKey();

// Lifecycle
await runtime.suspend();
const { agent: reactivated, keyPair: freshKeyPair } = await runtime.reactivate();
await runtime.revoke();

Agent Runtime Methods

| Method | Description | |--------|-------------| | signedFetch(path, options?) | Core signed HTTP request with Ed25519 headers | | checkPermission(resource, action, context?) | Server-side permission check | | checkPermissions(checks[]) | Batch server-side check | | fetchPermissions() | Fetch + cache allow/deny permission lists | | hasPermission(resource) | Client-side cached check (deny-first, 5-min TTL) | | invalidatePermissionsCache() | Clear cached permissions | | delegate(params) | Create a delegation token | | callTool(params) | MCP JSON-RPC proxy call with double-signed request | | rotateKey() | Generate new keypair and register with server | | suspend() | Suspend agent | | reactivate() | Reactivate with new keypair | | revoke() | Permanently revoke agent | | getIdentityDocument() | Get signed identity document (public endpoint) | | getProfile() | Get agent profile (signed request) | | getPublicKey() | Return base64url public key (sync) |


Cryptography

Ed25519 key generation, signing, and verification via @noble/ed25519 (pure JS, no native dependencies).

import { generateKeyPair, sign, verify, buildSignaturePayload, sha256Hash } from '@authora/sdk';

// Generate Ed25519 keypair (base64url encoded)
const { privateKey, publicKey } = generateKeyPair();

// Sign a message
const signature = sign('hello world', privateKey);

// Verify a signature
const valid = verify('hello world', signature, publicKey);

// Build the canonical signature payload for HTTP requests
const payload = buildSignaturePayload('POST', '/api/v1/agents', '2025-01-01T00:00:00.000Z', '{}');

// SHA-256 hash (base64url)
const hash = sha256Hash('request body');

MCP Middleware (Server-Side)

Three components for MCP tool servers to verify and authorize agent requests:

AuthoraMCPGuard (Express Middleware)

import { AuthoraMCPGuard, protectTool } from '@authora/sdk';

const guard = new AuthoraMCPGuard({
  resolvePublicKey: async (agentId) => {
    // Fetch agent's public key from your store or Authora API
    return publicKeyBase64url;
  },
  requiredPermissions: ['mcp:myserver:tool.*'],
  onDenied: (agentId, reason) => console.log(`Denied ${agentId}: ${reason}`),
});

// As Express middleware
app.use('/mcp', guard.middleware());

// Or protect individual tool handlers
app.post('/tools/echo', protectTool(guard, async (req, res) => {
  res.json({ result: req.body.params.arguments.message });
}));

AuthoraMCPMiddleware (Handler Wrapping)

import { AuthoraMCPMiddleware } from '@authora/sdk';

const middleware = new AuthoraMCPMiddleware({
  resolvePublicKey: async (agentId) => publicKeyBase64url,
});

// Wrap MCP tool handlers
const protectedHandler = middleware.wrapHandler(async (args, context) => {
  // context.agentId, context.verified, context.delegationToken
  return { result: args.message };
});

Permission Matching (Client-Side)

import { matchPermission, matchAnyPermission } from '@authora/sdk';

matchPermission('agents:*', 'agents:read');          // true
matchPermission('mcp:*:tool.read_*', 'mcp:s1:tool.read_files'); // true
matchPermission('agents:*', 'agents:read:all');      // false (segment count mismatch)

matchAnyPermission(['files:read', 'files:*'], 'files:write'); // true

TypeScript

All types are exported from the package root:

import type {
  Agent,
  AgentStatus,
  Role,
  Policy,
  PolicyEffect,
  Delegation,
  PermissionCheckResult,
  PaginatedList,
} from '@authora/sdk';

Examples

See the examples/ directory for runnable code samples including a quickstart.

Requirements

  • Node.js 18+ (for native fetch support) or any modern browser
  • No runtime dependencies

License

MIT