{"_id":"@aporthq/sdk-node","_rev":"4-fde42f5acae106443466b4d904129654","name":"@aporthq/sdk-node","dist-tags":{"latest":"0.1.3"},"versions":{"0.1.0":{"name":"@aporthq/sdk-node","version":"0.1.0","keywords":["agent-passport","ai","authentication","verification","aport","mcp","middleware"],"author":{"name":"APort Team","email":"team@aport.io"},"license":"MIT","_id":"@aporthq/sdk-node@0.1.0","maintainers":[{"name":"uchi4jah","email":"uchi.uchibeke@gmail.com"}],"homepage":"https://aport.io","bugs":{"url":"https://github.com/aporthq/agent-passport/issues"},"dist":{"shasum":"a9c2d2d9f38fe4752e5f285f41befb5c83a1a111","tarball":"https://registry.npmjs.org/@aporthq/sdk-node/-/sdk-node-0.1.0.tgz","fileCount":27,"integrity":"sha512-+8LvxadPnEaEOVz1hqGyt5/Bx4V+cwzRmO+UxFygt21aJxad9PtwvRmxCqxxbT0YZXHd3khYnhevHWzlfFhIOw==","signatures":[{"sig":"MEQCICUIhjJrv6DFEqNlK6kZXEgRc9D2D1S6BINI9hYy8RsMAiARKTgN90V0LA+OKqtnxW7gDS8ZGeIdT2f3v5K65CU4Xw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":38276},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"gitHead":"9c3fc987df872aeef5eff4e3341d942faf48c154","scripts":{"dev":"tsc --watch","test":"jest src/thin-client.test.ts","build":"tsc","prepublishOnly":"npm run build"},"_npmUser":{"name":"uchi4jah","email":"uchi.uchibeke@gmail.com"},"repository":{"url":"git+https://github.com/aporthq/agent-passport.git","type":"git","directory":"sdk/node"},"_npmVersion":"10.8.2","description":"Node.js SDK for AI Agent Passport Registry","directories":{},"_nodeVersion":"20.19.5","dependencies":{},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-node_0.1.0_1759293079091_0.9083115531875958","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@aporthq/sdk-node","version":"0.1.1","keywords":["agent-passport","ai","authentication","verification","aport","mcp","middleware"],"author":{"name":"APort Team","email":"team@aport.io"},"license":"MIT","_id":"@aporthq/sdk-node@0.1.1","maintainers":[{"name":"uchi4jah","email":"uchi.uchibeke@gmail.com"}],"homepage":"https://aport.io","bugs":{"url":"https://github.com/aporthq/aport-sdks-and-middlewares/issues"},"dist":{"shasum":"5edd6a4794bdccfefe1106409a7578a7b44dafb7","tarball":"https://registry.npmjs.org/@aporthq/sdk-node/-/sdk-node-0.1.1.tgz","fileCount":27,"integrity":"sha512-8piCHFWdfNjLObT43/jCUkXw2gnDA1FmqG63ESX0yYZW3JQe77J/P+OaGuY00UntRdR9MhLxLsglsSobrqznhA==","signatures":[{"sig":"MEQCIHoUN7GOGubqsaI1WBZFo99+bAXYqbcVAf9TxNbbRHeeAiAz92VUqWPkNqY5v9Dp5Vm8UiI/F7LSZWqU2qk0D1liog==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":38951},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"gitHead":"e89d47ffcfd0446260c02c5d37a9d5f7420fc35b","scripts":{"dev":"tsc --watch","test":"jest src/thin-client.test.ts","build":"tsc","prepublishOnly":"npm run build"},"_npmUser":{"name":"uchi4jah","email":"uchi.uchibeke@gmail.com"},"repository":{"url":"git+https://github.com/aporthq/aport-sdks-and-middlewares.git","type":"git","directory":"sdk/node"},"_npmVersion":"11.5.2","description":"Node.js SDK for The Passport for AI Agents","directories":{},"_nodeVersion":"20.17.0","dependencies":{},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-node_0.1.1_1761504258977_0.07496655244127326","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@aporthq/sdk-node","version":"0.1.2","keywords":["agent-passport","ai","authentication","verification","aport","mcp","middleware"],"author":{"name":"APort Team","email":"team@aport.io"},"license":"MIT","_id":"@aporthq/sdk-node@0.1.2","maintainers":[{"name":"uchi4jah","email":"uchi.uchibeke@gmail.com"}],"homepage":"https://aport.io","bugs":{"url":"https://github.com/aporthq/aport-sdks-and-middlewares/issues"},"dist":{"shasum":"ea8a9b9b52cbca7f29a0cb60c18b16feed7668a2","tarball":"https://registry.npmjs.org/@aporthq/sdk-node/-/sdk-node-0.1.2.tgz","fileCount":27,"integrity":"sha512-M0wvg/FQPmymEh5V4y9V3DZM5P6dj5Qlzk/q3TayHBFPxrF28gJ/uljqQnp8FdarfEC7xhf6/whEpEd5oKvakw==","signatures":[{"sig":"MEUCICCznV/bEViivDDYDznIkMLh1sM/IlR+N2IxP64w8+scAiEA01zQuxCwxddfwUg9Uc0LX23CwvJloSLTh0Ko+3qGIcM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":39102},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"gitHead":"7958e3bb56760dff0de9d6dab70f789a517b03b1","scripts":{"dev":"tsc --watch","test":"jest src/thin-client.test.ts","build":"tsc","prepublishOnly":"npm run build","publish:public":"npm run build && npm publish --access public","publish:dry-run":"npm run build && npm publish --dry-run --access public"},"_npmUser":{"name":"uchi4jah","email":"uchi.uchibeke@gmail.com"},"repository":{"url":"git+https://github.com/aporthq/aport-sdks-and-middlewares.git","type":"git","directory":"sdk/node"},"_npmVersion":"11.5.2","description":"Node.js SDK for The Passport for AI Agents","directories":{},"_nodeVersion":"20.17.0","dependencies":{},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk-node_0.1.2_1763509714054_0.9183925744587651","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@aporthq/sdk-node","version":"0.1.3","description":"Node.js SDK for The Passport for AI Agents","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"tsc","test":"jest src/thin-client.test.ts","dev":"tsc --watch","prepublishOnly":"npm run build","publish:dry-run":"npm run build && npm publish --dry-run --access public","publish:public":"npm run build && npm publish --access public"},"keywords":["agent-passport","ai","authentication","verification","aport","mcp","middleware"],"author":{"name":"APort Team","email":"team@aport.io"},"license":"MIT","dependencies":{},"devDependencies":{"@types/jest":"^29.5.0","@types/node":"^20.0.0","jest":"^29.5.0","ts-jest":"^29.1.0","typescript":"^5.0.0"},"engines":{"node":">=18.0.0"},"repository":{"type":"git","url":"git+https://github.com/aporthq/aport-sdks-and-middlewares.git","directory":"sdk/node"},"homepage":"https://aport.io","bugs":{"url":"https://github.com/aporthq/aport-sdks-and-middlewares/issues"},"publishConfig":{"access":"public"},"_id":"@aporthq/sdk-node@0.1.3","gitHead":"7958e3bb56760dff0de9d6dab70f789a517b03b1","_nodeVersion":"20.17.0","_npmVersion":"11.5.2","dist":{"integrity":"sha512-930SObgzu+3H0K6tBxM7eNjL9sdvjTuR5sVwoEvyXDkuHPB/puAsrUZ4GD/GVWFUDpcNLihm7NJ8NJwcceqtjQ==","shasum":"31bf343f53603be282a74cfd29d5d75765674ad4","tarball":"https://registry.npmjs.org/@aporthq/sdk-node/-/sdk-node-0.1.3.tgz","fileCount":27,"unpackedSize":39102,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIBMm9nv0qYWWNyue8X6Hh2aPM8z1D62aZtFNbWMDgBmpAiEA+pRYXONxdUn0VFmH6LptfXLRzYdpycIV+evUq1Hfs6U="}]},"_npmUser":{"name":"uchi4jah","email":"uchi.uchibeke@gmail.com"},"directories":{},"maintainers":[{"name":"uchi4jah","email":"uchi.uchibeke@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sdk-node_0.1.3_1763509898754_0.8348043866246879"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-01T04:31:18.923Z","modified":"2025-11-18T23:51:39.143Z","0.1.0":"2025-10-01T04:31:19.304Z","0.1.1":"2025-10-26T18:44:19.185Z","0.1.2":"2025-11-18T23:48:34.271Z","0.1.3":"2025-11-18T23:51:38.953Z"},"bugs":{"url":"https://github.com/aporthq/aport-sdks-and-middlewares/issues"},"author":{"name":"APort Team","email":"team@aport.io"},"license":"MIT","homepage":"https://aport.io","keywords":["agent-passport","ai","authentication","verification","aport","mcp","middleware"],"repository":{"type":"git","url":"git+https://github.com/aporthq/aport-sdks-and-middlewares.git","directory":"sdk/node"},"description":"Node.js SDK for The Passport for AI Agents","maintainers":[{"name":"uchi4jah","email":"uchi.uchibeke@gmail.com"}],"readme":"# Agent Passport Node.js SDK\n\nA production-grade thin Node.js SDK for The Passport for AI Agents, providing easy integration with agent authentication and policy verification via API calls. All policy logic, counters, and enforcement happen on the server side.\n\n## Features\n\n- ✅ **Thin Client Architecture** - No policy logic, no Cloudflare imports, no counters\n- ✅ **Production Ready** - Timeouts, retries, proper error handling, Server-Timing support\n- ✅ **Type Safe** - Full TypeScript support with comprehensive type definitions\n- ✅ **Idempotency Support** - Both header and body idempotency key support\n- ✅ **Local Token Validation** - JWKS support for local decision token validation\n- ✅ **Multiple Environments** - Production, sandbox, and self-hosted enterprise support\n- ✅ **Zero Dependencies** - Uses native Node.js 18+ fetch API\n\n## Installation\n\n```bash\nnpm install @aporthq/sdk-node\n```\n\n**Requirements:** Node.js 18.0.0 or higher\n\n## 💰 Amount Handling\n\n**All monetary amounts must be passed in cents (minor currency units).**\n\n### Examples:\n- `$5.00` → `500` cents\n- `$100.00` → `10000` cents  \n- `$0.50` → `50` cents\n\n### API Fields:\n- **`amount`**: Integer value in cents (e.g., `500` for $5.00) - **RECOMMENDED**\n- **`amount_minor`**: Integer value in cents (e.g., `500` for $5.00) - **LEGACY, use `amount` instead**\n\n## Quick Start\n\n```javascript\nimport { APortClient, PolicyVerifier, AportError } from '@aporthq/sdk-node';\n\n// Initialize client for production\nconst client = new APortClient({\n  baseUrl: 'https://api.aport.io', // Production API\n  apiKey: 'your-api-key', // Optional\n  timeoutMs: 800 // Optional: Request timeout (default: 800ms)\n});\n\n// Or for sandbox/testing\nconst sandboxClient = new APortClient({\n  baseUrl: 'https://sandbox.aport.io', // Sandbox API\n  apiKey: 'your-sandbox-key'\n});\n\n// Or for self-hosted enterprise\nconst enterpriseClient = new APortClient({\n  baseUrl: 'https://your-company.aport.io', // Your self-hosted instance\n  apiKey: 'your-enterprise-key'\n});\n\n// Generic policy verification - works with any policy\ntry {\n  const decision = await client.verifyPolicy(\n    'your-agent-id',\n    'finance.payment.refund.v1', // Any policy from ./policies\n    {\n      amount: 1000,  // Amount in cents ($10.00)\n      currency: 'USD',\n      order_id: 'order_123',\n      reason: 'defective'\n    },\n    'unique-key-123' // Optional idempotency key\n  );\n\n  if (decision.allow) {\n    console.log('✅ Policy verification passed!');\n    console.log(`Decision ID: ${decision.decision_id}`);\n    console.log(`Assurance Level: ${decision.assurance_level}`);\n  } else {\n    console.log('❌ Policy verification failed!');\n    decision.reasons?.forEach(reason => {\n      console.log(`  - [${reason.severity}] ${reason.code}: ${reason.message}`);\n    });\n  }\n} catch (error) {\n  if (error instanceof AportError) {\n    console.error(`API Error ${error.status}:`, error.message);\n    console.error('Reasons:', error.reasons);\n    console.error('Decision ID:', error.decision_id);\n  } else {\n    console.error('Policy verification failed:', error.message);\n  }\n}\n```\n\n## Environments\n\nThe SDK supports different environments through the `baseUrl` parameter:\n\n- **Production**: `https://api.aport.io` - The main APort API\n- **Sandbox**: `https://sandbox.aport.io` - Testing environment with mock data\n- **Self-hosted**: `https://your-domain.com` - Your own APort instance\n\nYou can also host your own APort service for complete control over policy verification and data privacy.\n\n## API Reference\n\n### `APortClient`\n\nThe core client for interacting with the APort API endpoints.\n\n#### `constructor(options: APortClientOptions)`\nInitializes the APort client.\n- `options.baseUrl` (string): The base URL of your APort API (e.g., `https://api.aport.io`).\n- `options.apiKey` (string, optional): Your API Key for authenticated requests.\n- `options.timeoutMs` (number, optional): Request timeout in milliseconds (default: 800ms).\n\n#### `verifyPolicy(agentId: string, policyId: string, context?: Record<string, any>, idempotencyKey?: string): Promise<PolicyVerificationResponse>`\nVerifies a policy against an agent by calling the `/api/verify/policy/:pack_id` endpoint.\n- `agentId` (string): The ID of the agent.\n- `policyId` (string): The ID of the policy pack (e.g., `finance.payment.refund.v1`, `code.release.publish.v1`).\n- `context` (Record<string, any>, optional): The policy-specific context data.\n- `idempotencyKey` (string, optional): An optional idempotency key for the request.\n\n#### `getDecisionToken(agentId: string, policyId: string, context?: Record<string, any>): Promise<string>`\nRetrieves a short-lived decision token for near-zero latency local validation. Calls `/api/verify/token/:pack_id`.\n\n#### `validateDecisionToken(token: string): Promise<PolicyVerificationResponse>`\nValidates a decision token via server (for debugging). Calls `/api/verify/token/validate`.\n\n#### `getPassportView(agentId: string): Promise<any>`\nRetrieves a small, cacheable view of an agent's passport (limits, assurance, status) for display purposes (e.g., about pages, debugging). Calls `/api/passports/:id/verify_view`.\n\n#### `validateDecisionTokenLocal(token: string): Promise<PolicyVerificationResponse>`\nValidates a decision token locally using JWKS (recommended for production). Falls back to server validation if JWKS unavailable.\n\n#### `getJwks(): Promise<Jwks>`\nRetrieves the JSON Web Key Set for local token validation. Cached for 5 minutes.\n\n### `PolicyVerifier`\n\nA convenience class that wraps `APortClient` to provide policy-specific verification methods.\n\n#### `constructor(client: APortClient)`\nInitializes the PolicyVerifier with an `APortClient` instance.\n\n#### `verifyRefund(agentId: string, context: { amount: number; currency: string; order_id: string; reason?: string; }, idempotencyKey?: string): Promise<PolicyVerificationResponse>`\nVerifies the `finance.payment.refund.v1` policy.\n\n#### `verifyRepository(agentId: string, context: { operation: \"create_pr\" | \"merge\"; repository: string; base_branch?: string; pr_size_kb?: number; file_paths?: string[]; github_actor?: string; title?: string; description?: string; }, idempotencyKey?: string): Promise<PolicyVerificationResponse>`\nVerifies the `code.repository.merge.v1` policy.\n\n#### Additional Policy Methods\nThe `PolicyVerifier` also includes convenience methods for other policies:\n- `verifyRelease()` - Verifies the `code.release.publish.v1` policy\n- `verifyDataExport()` - Verifies the `data.export.create.v1` policy  \n- `verifyMessaging()` - Verifies the `messaging.message.send.v1` policy\n\nThese methods follow the same pattern as `verifyRefund()` and `verifyRepository()`.\n\n## Error Handling\n\nThe SDK throws `AportError` objects for API request failures with detailed error information.\n\n```javascript\nimport { AportError } from '@aporthq/sdk-node';\n\ntry {\n  await client.verifyPolicy(\"invalid-agent\", \"finance.payment.refund.v1\", {});\n} catch (error) {\n  if (error instanceof AportError) {\n    console.error(`Status: ${error.status}`);\n    console.error(`Message: ${error.message}`);\n    console.error(`Reasons:`, error.reasons);\n    console.error(`Decision ID:`, error.decision_id);\n    console.error(`Server Timing:`, error.serverTiming);\n  } else {\n    console.error(\"Unexpected error:\", error.message);\n  }\n}\n```\n\n### Error Types\n\n- **`AportError`**: API request failures with status codes, reasons, and decision IDs\n- **Timeout Errors**: 408 status with `TIMEOUT` reason code\n- **Network Errors**: 0 status with `NETWORK_ERROR` reason code\n\n## Production Features\n\n### Idempotency Support\nThe SDK supports idempotency keys in both the request body and the `Idempotency-Key` header (header takes precedence).\n\n```javascript\nconst decision = await client.verifyPolicy(\n  \"agent-123\",\n  \"finance.payment.refund.v1\",\n  { amount: 100, currency: \"USD\" },  // Amount in cents ($1.00)\n  \"unique-idempotency-key\" // Sent in both header and body\n);\n```\n\n### Server-Timing Support\nThe SDK automatically captures and exposes Server-Timing headers for performance monitoring.\n\n```javascript\nconst decision = await client.verifyPolicy(\"agent-123\", \"finance.payment.refund.v1\", {});\nconsole.log(\"Server timing:\", decision._meta?.serverTiming);\n// Example: \"cache;dur=5,db;dur=12\"\n```\n\n### Local Token Validation\nFor high-performance scenarios, use local token validation with JWKS:\n\n```javascript\n// Get JWKS (cached for 5 minutes)\nconst jwks = await client.getJwks();\n\n// Validate token locally (no server round-trip)\nconst decision = await client.validateDecisionTokenLocal(token);\n```\n\n### Timeout and Retry Configuration\nConfigure timeouts and retry behavior:\n\n```javascript\nconst client = new APortClient({\n  baseUrl: \"https://api.aport.io\",\n  apiKey: \"your-key\",\n  timeoutMs: 500 // 500ms timeout\n});\n```\n\n## TypeScript Support\n\nThe SDK includes full TypeScript definitions for all classes, interfaces, and types.\n\n```typescript\nimport { APortClient, APortClientOptions, PolicyVerificationResponse } from '@aporthq/sdk-node';\n\nconst options: APortClientOptions = {\n  baseUrl: 'https://api.aport.io',\n  apiKey: 'my-secret-key',\n  timeoutMs: 800\n};\n\nconst client: APortClient = new APortClient(options);\n\nconst decision: PolicyVerificationResponse = await client.verifyPolicy(\n  \"agent_123\", \n  \"finance.payment.refund.v1\", \n  { amount: 500, currency: \"EUR\" }  // Amount in cents (€5.00)\n);\n```\n\n## License\n\nMIT","readmeFilename":"README.md"}