{"_id":"@aroha-sdk/delegation","_rev":"2-e465d217d09ae82c669f4eacd5ed700b","name":"@aroha-sdk/delegation","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@aroha-sdk/delegation","version":"0.1.0","keywords":["aroha","agent","delegation","mandate","multi-agent","agent-network","attenuation","capability"],"license":"MIT","_id":"@aroha-sdk/delegation@0.1.0","maintainers":[{"name":"aroha-labs","email":"projectmed99@gmail.com"}],"dist":{"shasum":"7d78a3cc3b521c0d983f88e788e033d78438f4ca","tarball":"https://registry.npmjs.org/@aroha-sdk/delegation/-/delegation-0.1.0.tgz","fileCount":28,"integrity":"sha512-ZFBw6Lji2N6xdfCDr+NXZAJm28vz6ZXtXm3+lG/4nkVWbsMTbydPDOqYl0xlH9leLKSU9Y1KU/Wo/P+OQGrpJQ==","signatures":[{"sig":"MEUCIQDFXoD3T/pmi6cY9GtRBxlY1ivs95XtLfvKzd/j+hpBnAIgafJXHZZbNcX45vOLZtPupt9UjGUGPriAzW/Q1iuSoh4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":112208},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"c1cbdb4dac406bef0c58c98b71bb49b0cdaea8ad","scripts":{"dev":"tsc -p tsconfig.json --watch","test":"vitest run","build":"tsc -p tsconfig.json"},"_npmUser":{"name":"aroha-labs","email":"projectmed99@gmail.com"},"_npmVersion":"11.9.0","description":"Turnkey multi-hop delegation for Aroha agent networks — verified mandate chains, auto-attenuating ctx.delegate(), depth enforcement, and stitched receipts on top of @aroha-sdk/run.","directories":{},"_nodeVersion":"24.14.0","dependencies":{"@noble/hashes":"^1.4.0","@aroha-sdk/run":"*","@noble/ed25519":"^2.1.0","@aroha-sdk/core":"*","@aroha-sdk/credentials":"*"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^1.6.0","typescript":"^5.4.5"},"_npmOperationalInternal":{"tmp":"tmp/delegation_0.1.0_1784202138538_0.8419804012572585","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@aroha-sdk/delegation","version":"0.2.0","description":"Turnkey multi-hop delegation for Aroha agent networks — verified mandate chains, auto-attenuating ctx.delegate(), depth enforcement, and stitched receipts on top of @aroha-sdk/run.","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":"./dist/index.js","types":"./dist/index.d.ts"}},"scripts":{"build":"tsc -p tsconfig.json","test":"vitest run","dev":"tsc -p tsconfig.json --watch"},"dependencies":{"@aroha-sdk/core":"*","@aroha-sdk/credentials":"*","@aroha-sdk/run":"*","@noble/ed25519":"^2.1.0","@noble/hashes":"^1.4.0"},"devDependencies":{"typescript":"^5.4.5","vitest":"^1.6.0"},"engines":{"node":">=22.0.0"},"keywords":["aroha","agent","delegation","mandate","multi-agent","agent-network","attenuation","capability"],"license":"MIT","gitHead":"8fc993e7202bf4856883d3f7bd8daf1ae8e73c8a","_id":"@aroha-sdk/delegation@0.2.0","_nodeVersion":"24.18.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-mfnSsv6B/SUmCbh8wCzhr0EWo3Um04SAkaDu5wSMTPVhlCbO+USzg7j1gH3YcGb3muNEjHymoKUashJklIWTlA==","shasum":"37a0c662d7377b97a4c08192fa49a6daf03eb7c7","tarball":"https://registry.npmjs.org/@aroha-sdk/delegation/-/delegation-0.2.0.tgz","fileCount":34,"unpackedSize":134097,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIAmQQtlEvdsQN8aWpbB/MKlOXJv/QQ/UX3bhT5vhSvcuAiAqgSYi4wJom4vFwjDIV508+6ZNPc07/2M7IyRsylCxLw=="}]},"_npmUser":{"name":"aroha-labs","email":"projectmed99@gmail.com"},"directories":{},"maintainers":[{"name":"aroha-labs","email":"projectmed99@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/delegation_0.2.0_1786619410131_0.08763812492510459"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-16T11:42:18.387Z","modified":"2026-08-13T11:10:10.442Z","0.1.0":"2026-07-16T11:42:18.699Z","0.2.0":"2026-08-13T11:10:10.280Z"},"license":"MIT","keywords":["aroha","agent","delegation","mandate","multi-agent","agent-network","attenuation","capability"],"description":"Turnkey multi-hop delegation for Aroha agent networks — verified mandate chains, auto-attenuating ctx.delegate(), depth enforcement, and stitched receipts on top of @aroha-sdk/run.","maintainers":[{"name":"aroha-labs","email":"projectmed99@gmail.com"}],"readme":"# @aroha-sdk/delegation\n\n![Beta](https://img.shields.io/badge/status-beta-blue) ![npm](https://img.shields.io/npm/v/@aroha-sdk/delegation)\n\n**Turnkey multi-hop delegation for agent networks.** Build webs of agents — A delegates to B, which delegates to C and D — where every hop carries signed, verifiable, shrinking authority, and a receipt tree comes back to whoever started it.\n\nThe cryptographic primitives live in `@aroha-sdk/credentials`; the single-agent server lives in `@aroha-sdk/run`. This package is the composition layer that turns \"multi-hop agent web\" from a custom verify/attenuate/call pipeline in every node into a few lines per node.\n\n```\nA (root issuer) ──► B (orchestrator) ──► C (searcher)\n                                     └─► D (summariser)\n```\n\n## A node in the web\n\n```typescript\nimport { serveDelegated, staticResolver } from \"@aroha-sdk/delegation\";\n\nserveDelegated(\"orchestrator\", {\n  identity: { did: \"did:aroha:acme:orchestrator\", privateKey: myKey },\n  trustAnchors: { \"did:aroha:human:alice\": alicePublicKeyB64 },\n  resolvePublicKey: registryResolver(),   // or staticResolver({...}) for closed networks\n}, async (ctx) => {\n  ctx.assertCapability(\"research\");        // throws unless the verified mandate allows it\n\n  // Delegate onward — authority is attenuated automatically:\n  // subset scope, depth − 1, blocked list carried forward, same correlationId\n  const search  = await ctx.delegate(searcherDidHash, ctx.message,\n                                     { allowed: [\"web-search\"] });\n  const summary = await ctx.delegate(summariserDidHash, search.message,\n                                     { allowed: [\"summarise\"] });\n  return summary.message;\n}).start(8000);\n```\n\nEvery request to this agent **must** carry a valid mandate chain or it is rejected with 400 before your handler runs. Fail closed, always.\n\n## Starting a chain (the root issuer)\n\n```typescript\nimport { issueDelegation, callDelegated } from \"@aroha-sdk/delegation\";\n\nconst { envelope } = await issueDelegation(\n  { did: \"did:aroha:human:alice\", privateKey: aliceKey },\n  orchestratorDid,\n  {\n    allowed: [\"research\", \"web-search\", \"summarise\"],\n    constraints: { maxDelegationDepth: 1 },  // B may delegate once; C/D may not\n    ttlMs: 60_000,\n  },\n);\n\nconst res = await callDelegated(orchestratorEndpoint, \"history of agent protocols\", envelope);\n\nconsole.log(res.message);\nconsole.log(res.receipts[0]);          // B's receipt, with C's and D's nested in .children\n```\n\n## What the chain guarantees\n\nEach hop appends one signed mandate to the envelope riding `context.aroha`. `verifyMandateChain()` — run automatically by every `serveDelegated` node — checks the whole path, root → leaf:\n\n| Check | Attack it stops |\n|---|---|\n| Every link's Ed25519 signature | Forged or tampered mandates |\n| Root key pinned to `trustAnchors` | An attacker minting their own \"root\" |\n| `grantor(i) === grantee(i−1)` + `parentMandateId` linkage | Splicing a mandate from another chain |\n| `allowed(i) ⊆ allowed(i−1)` | Scope widening mid-chain |\n| `blocked` list must survive every hop | Laundering a ban through a sub-agent |\n| Child expiry ≤ parent expiry | Zombie authority outliving its grant |\n| **`maxDelegationDepth` strictly decrements** | Runaway agent-spawns-agent recursion |\n\nDepth is enforced here, at the chain level — `maxDelegationDepth: 0` means the mandate is a dead end, and `ctx.delegate()` refuses with `DELEGATION_DEPTH_EXCEEDED` before a child token is even signed.\n\n## Receipts come back as a tree\n\nEvery node builds a `TaskReceipt` automatically (actions, violations, timings) and returns it as a response artifact. `ctx.delegate()` collects downstream receipts and nests them, so the root issuer receives the **whole execution tree** under one `correlationId`:\n\n```\norchestrator (complete)\n ├─ searcher   (complete) — actions: web-search\n └─ summariser (complete) — actions: summarise\n```\n\n## Runnable example\n\nA full A → B → (C, D) web on localhost — including a blocked over-delegation, a rejected forged root, and an out-of-grant refusal — ships in the repo at `examples/delegation-web/demo.mjs`.\n\n## Mandate verification without @aroha-sdk/run\n\n`serveDelegated` above wraps `@aroha-sdk/run`'s `serve()` end to end — the\nright choice when you want its streaming/approval/receipt machinery too. If\nyou're hosting with a raw `ArohaServer` from `@aroha-sdk/core` instead and\njust need mandate-chain verification, mount it directly as middleware — the\nsame composability pattern `@aroha-sdk/credentials`'\n`createRbacMiddleware()` already uses:\n\n```typescript\nimport { ArohaServer } from \"@aroha-sdk/core\";\nimport { createDelegationMiddleware, getVerifiedMandate } from \"@aroha-sdk/delegation\";\n\nconst server = new ArohaServer({\n  agentDID: \"did:aroha:acme:orchestrator\",\n  didDocument,\n  port: 8000,\n  resolvePublicKey,\n  middleware: [\n    createDelegationMiddleware({\n      did: \"did:aroha:acme:orchestrator\",\n      trustAnchors: { \"did:aroha:human:alice\": alicePublicKeyB64 },\n    }),\n  ],\n  onMessage: async (envelope, respond) => {\n    const verified = getVerifiedMandate(envelope); // undefined only if require:false and none was sent\n    // ...\n  },\n});\n```\n\nNo `@aroha-sdk/run` dependency in this path. You lose `serveDelegated`'s\nautomatic receipt stitching and `ctx.delegate()` convenience — this only\nanswers \"is there a valid mandate chain granting the caller access,\" the\nsame boundary RBAC draws around permission checks.\n\n## Wire format\n\nNo new protocol: the envelope rides the existing `RunRequest.context` under the `aroha` key, so any `/v1/run`-speaking agent can participate.\n\n```jsonc\n{ \"message\": \"…\", \"context\": { \"aroha\": {\n  \"v\": 1,\n  \"chain\": [\"<rootToken>\", \"<childToken>\", …],\n  \"rootKeyB64\": \"<root issuer's Ed25519 public key>\",\n  \"correlationId\": \"…\"\n}}}\n```\n\n## License\n\nMIT © Aroha Labs\n","readmeFilename":"README.md"}