{"_id":"@aauth/agent","_rev":"5-aeef0b909d17c987972107ffe6427773","name":"@aauth/agent","dist-tags":{"latest":"4.1.0"},"versions":{"3.0.0":{"name":"@aauth/agent","version":"3.0.0","keywords":["aauth","agent","http-signatures"],"author":{"name":"Dick Hardt","email":"dick.hardt@hello.coop"},"license":"MIT","_id":"@aauth/agent@3.0.0","maintainers":[{"name":"dickhardt","email":"dickhardt@gmail.com"},{"name":"rohanharikr","email":"rohanharikumar80@gmail.com"}],"homepage":"https://github.com/aauth-dev/packages-js#readme","bugs":{"url":"https://github.com/aauth-dev/packages-js/issues"},"dist":{"shasum":"faf03b1fd5eba2d83f74984edabf4486327a0e1c","tarball":"https://registry.npmjs.org/@aauth/agent/-/agent-3.0.0.tgz","fileCount":54,"integrity":"sha512-tnK54VkZrByyXoyCoqquJzU2frIsa0o1xm4JXrfAFu60O1fTAjEKj5iXTprZ22k62yFAQKaI9mzbBQeNL1S9Eg==","signatures":[{"sig":"MEUCIAmJR4A1wC53iND1P14WGrWzAqdXGxZ4RqtAcghbEbDLAiEAm/TGP2FyCk9n1A63jAB04RKxMSQcWtdlw9MJI2eAkPs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":254920},"type":"module","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"scripts":{"build":"tsc","prepublishOnly":"npm run build"},"_npmUser":{"name":"dickhardt","email":"dickhardt@gmail.com"},"repository":{"url":"git+https://github.com/aauth-dev/packages-js.git","type":"git","directory":"agent"},"_npmVersion":"11.16.0","description":"Agent-side AAuth protocol library — HTTP Signatures, person tokens, token exchange, deferred polling","directories":{},"_nodeVersion":"22.22.3","dependencies":{"@aauth/protocol":"^1.0.0","@hellocoop/httpsig":"^2.2.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.0.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/agent_3.0.0_1786635771322_0.47727607057429355","host":"s3://npm-registry-packages-npm-production"}},"3.0.1":{"name":"@aauth/agent","version":"3.0.1","keywords":["aauth","agent","http-signatures"],"author":{"name":"Dick Hardt","email":"dick.hardt@hello.coop"},"license":"MIT","_id":"@aauth/agent@3.0.1","maintainers":[{"name":"dickhardt","email":"dickhardt@gmail.com"},{"name":"rohanharikr","email":"rohanharikumar80@gmail.com"}],"homepage":"https://github.com/aauth-dev/packages-js#readme","bugs":{"url":"https://github.com/aauth-dev/packages-js/issues"},"dist":{"shasum":"db1570847f176774af6b019c3a9e1e32fe9655d4","tarball":"https://registry.npmjs.org/@aauth/agent/-/agent-3.0.1.tgz","fileCount":54,"integrity":"sha512-6g6Qdc5YlhNB+dhoZv/givtrZMUBQtlA94kJB4j6aEHoAUW1tfZgVkDOSlwwskIa3MX73mBYqnfV5csYN4ryRg==","signatures":[{"sig":"MEYCIQDbTEqcpXSGRl5nqrcmynI5AmQEoBrRE9WPgC8ArkJ3vwIhAK8AaQUOE7zaYX8lafyoCbUbSjopOBh0OjAEl5mN16Z+","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aauth%2fagent@3.0.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":254920},"type":"module","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"8998c7250424a6505b154f5ce22638df7db030e6","scripts":{"build":"tsc","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:7491c0da-9615-4dee-b535-4208f554bff7"}},"repository":{"url":"git+https://github.com/aauth-dev/packages-js.git","type":"git","directory":"agent"},"_npmVersion":"11.17.0","description":"Agent-side AAuth protocol library — HTTP Signatures, person tokens, token exchange, deferred polling","directories":{},"_nodeVersion":"24.19.0","dependencies":{"@aauth/protocol":"^1.0.0","@hellocoop/httpsig":"^2.2.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.0.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/agent_3.0.1_1786706020208_0.5552231821069935","host":"s3://npm-registry-packages-npm-production"}},"3.0.2":{"name":"@aauth/agent","version":"3.0.2","keywords":["aauth","agent","http-signatures"],"author":{"name":"Dick Hardt","email":"dick.hardt@hello.coop"},"license":"MIT","_id":"@aauth/agent@3.0.2","maintainers":[{"name":"dickhardt","email":"dickhardt@gmail.com"},{"name":"rohanharikr","email":"rohanharikumar80@gmail.com"}],"homepage":"https://github.com/aauth-dev/packages-js#readme","bugs":{"url":"https://github.com/aauth-dev/packages-js/issues"},"dist":{"shasum":"086eb8bfc73f157bf43726a89634a37792501fd8","tarball":"https://registry.npmjs.org/@aauth/agent/-/agent-3.0.2.tgz","fileCount":54,"integrity":"sha512-ZD47/43v2ccY+avhASRpD9QTTQ8UHIieEdO5watiCLOPG2OFa4wjKxu06ymWTQFjbQHxqBSMTaluauT2Yy7ELg==","signatures":[{"sig":"MEQCIGAjqpB8lAFFFJHd4tZgC4zCzUPjb5NuIM1IFPVYBywZAiAdtEfJymoTBeywTZqkfgwJ47I+OOP8llScIZU/l0/gdQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aauth%2fagent@3.0.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":260695},"type":"module","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"7bd31a502904272267812e2cd26c231d0f950555","scripts":{"build":"tsc","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:7491c0da-9615-4dee-b535-4208f554bff7"}},"repository":{"url":"git+https://github.com/aauth-dev/packages-js.git","type":"git","directory":"agent"},"_npmVersion":"11.17.0","description":"Agent-side AAuth protocol library — HTTP Signatures, person tokens, token exchange, deferred polling","directories":{},"_nodeVersion":"24.19.0","dependencies":{"@aauth/protocol":"^1.0.0","@hellocoop/httpsig":"^2.2.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.0.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/agent_3.0.2_1788296156151_0.6465106485203929","host":"s3://npm-registry-packages-npm-production"}},"4.0.0":{"name":"@aauth/agent","version":"4.0.0","keywords":["aauth","agent","http-signatures"],"author":{"name":"Dick Hardt","email":"dick.hardt@hello.coop"},"license":"MIT","_id":"@aauth/agent@4.0.0","maintainers":[{"name":"dickhardt","email":"dickhardt@gmail.com"},{"name":"rohanharikr","email":"rohanharikumar80@gmail.com"}],"homepage":"https://github.com/aauth-dev/packages-js#readme","bugs":{"url":"https://github.com/aauth-dev/packages-js/issues"},"dist":{"shasum":"0a6634430eb98cef2fc452eb587541fd72dae1a7","tarball":"https://registry.npmjs.org/@aauth/agent/-/agent-4.0.0.tgz","fileCount":54,"integrity":"sha512-snCGivE2zjGI5nJiWllNVb1gg1Jm+lcqnZEbTF9CRqEASlkbnLoOmB1gqcNJzBt0CwQUGiXiKAUt0fp8J34OqQ==","signatures":[{"sig":"MEUCIG8kGW5YExbvdsMNwwvAk4Zm+2xkg41zXkqidrkcucLZAiEAkbNR1rzPEfy1XOkLqafDGrX1vKcGsq7XnfgBzdcKDEI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aauth%2fagent@4.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":291085},"type":"module","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"b19dd7d45d98b6a57b9ed469796f2beba9aa72bf","scripts":{"build":"tsc","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:7491c0da-9615-4dee-b535-4208f554bff7"}},"repository":{"url":"git+https://github.com/aauth-dev/packages-js.git","type":"git","directory":"agent"},"_npmVersion":"11.19.0","description":"Agent-side AAuth protocol library — HTTP Signatures, person tokens, token exchange, deferred polling","directories":{},"_nodeVersion":"24.20.0","dependencies":{"@aauth/protocol":"^1.0.0","@hellocoop/httpsig":"^2.4.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.0.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/agent_4.0.0_1788876621476_0.5078756342415456","host":"s3://npm-registry-packages-npm-production"}},"4.1.0":{"_id":"@aauth/agent@4.1.0","bugs":{"url":"https://github.com/aauth-dev/packages-js/issues"},"dist":{"shasum":"bc8d9bccc4700c662d24f8f6eef63eb3cde7d9e4","tarball":"https://registry.npmjs.org/@aauth/agent/-/agent-4.1.0.tgz","fileCount":54,"integrity":"sha512-GUJFkyP5P8VktT7sEwMQd7uATFLTixPdQD0yazi523fRdHh3czEl6iWHu9zdgg+WYr5zV0v5XvIrZOdJn3zQEA==","signatures":[{"sig":"MEQCIDp9Fitoa8vipo1oOLAJbSrmO6VnvIkeKw1pFlWoTiTVAiB9SVDZ/wQNxl1jQ7ea5kKCM5nvQtKaLSshHU2dvu0dCA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCDZIyKwfwbbxcnp7M8j5eF7NyhtHWSxVNGU6AHDJDbkQIhAOrcjzSe71ElOFylS5Oorgoo5BqMtrBDTb3IcJPygXVM"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aauth%2fagent@4.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":293428},"name":"@aauth/agent","type":"module","author":{"name":"Dick Hardt","email":"dick.hardt@hello.coop"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"0b29ec402b229933b5663f9ff8da337fff14a58f","license":"MIT","scripts":{"build":"tsc","prepublishOnly":"npm run build"},"version":"4.1.0","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:7491c0da-9615-4dee-b535-4208f554bff7"}},"homepage":"https://github.com/aauth-dev/packages-js#readme","keywords":["aauth","agent","http-signatures"],"repository":{"url":"git+https://github.com/aauth-dev/packages-js.git","type":"git","directory":"agent"},"_npmVersion":"11.19.0","description":"Agent-side AAuth protocol library — HTTP Signatures, person tokens, token exchange, deferred polling","directories":{},"maintainers":[{"name":"dickhardt","email":"dickhardt@gmail.com"},{"name":"rohanharikr","email":"rohanharikumar80@gmail.com"}],"_nodeVersion":"24.20.0","dependencies":{"@aauth/protocol":"^2.0.0","@hellocoop/httpsig":"^2.4.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.0.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/agent_4.1.0_1789422484157_0.6044011678722891"}}},"time":{"created":"2026-08-13T15:42:51.107Z","modified":"2026-09-14T21:48:04.587Z","3.0.0":"2026-08-13T15:42:51.479Z","3.0.1":"2026-08-14T11:13:40.413Z","3.0.2":"2026-09-01T20:55:56.289Z","4.0.0":"2026-09-08T14:10:21.616Z","4.1.0":"2026-09-14T21:48:04.240Z"},"bugs":{"url":"https://github.com/aauth-dev/packages-js/issues"},"author":{"name":"Dick Hardt","email":"dick.hardt@hello.coop"},"license":"MIT","homepage":"https://github.com/aauth-dev/packages-js#readme","keywords":["aauth","agent","http-signatures"],"repository":{"url":"git+https://github.com/aauth-dev/packages-js.git","type":"git","directory":"agent"},"description":"Agent-side AAuth protocol library — HTTP Signatures, person tokens, token exchange, deferred polling","maintainers":[{"name":"dickhardt","email":"dickhardt@gmail.com"},{"name":"rohanharikr","email":"rohanharikumar80@gmail.com"}],"readme":"# @aauth/agent\n\nThe agent-side AAuth protocol library. Signs HTTP requests, obtains person tokens, handles AAuth challenge-response flows, exchanges resource tokens for auth tokens at the person server, and polls 202 deferred responses.\n\nRenamed from `@aauth/mcp-agent`: the package contains no MCP and never did. Its only runtime dependencies are [`@aauth/protocol`](../protocol) and `@hellocoop/httpsig`.\n\nPart of [aauth-dev/packages-js](https://github.com/aauth-dev/packages-js). Protocol spec: [dickhardt/AAuth](https://github.com/dickhardt/AAuth).\n\n## Install\n\n```bash\nnpm install @aauth/agent\n```\n\n## Usage\n\n### `createAAuthFetch(options): FetchLike`\n\nCreates a protocol-aware fetch that handles the full AAuth flow: signs requests, obtains a person token when a resource challenges with `requirement=person-token`, parses 401 `AAuth-Requirement` challenges, exchanges resource tokens with the person server, caches auth tokens, handles `AAuth-Access` session tokens, and retries.\n\n```ts\nimport { createAAuthFetch } from '@aauth/agent'\n\nconst fetch = createAAuthFetch({\n  getKeyMaterial: async () => ({\n    signingKey: privateKeyJwk,\n    signatureKey: { type: 'jwt', jwt: agentToken }\n  }),\n  // Person server — the `ps` claim of the agent token.\n  authServerUrl: 'https://ps.example',\n  // Optional: declare protocol capabilities\n  capabilities: ['interaction', 'clarification'],\n  // Optional: the mission the agent is operating under, as the base64url\n  // SHA-256 of the approved mission blob. Forwarded when a person token is\n  // requested; it then flows person token → resource token → auth token.\n  missionS256: 'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk',\n  // Optional callbacks\n  onInteraction: (url, code) => {\n    console.log(`Visit ${url}?code=${code}`)\n  },\n  onClarification: async (question) => {\n    return prompt(question)\n  },\n  // Optional hints for the person server\n  justification: 'Read project files',\n  loginHint: 'user@example.com',\n  tenant: 'acme.com',\n  domainHint: 'acme.com',\n})\n\nconst response = await fetch('https://resource.example/api')\n```\n\nThere is no `AAuth-Mission` header in protocol -11 — it and its IANA registration were removed. A mission reaches a resource only inside a PS-issued token, as the `mission_s256` claim.\n\n### `requestPersonToken(options): Promise<PersonTokenResult>`\n\nRequests a person token from the PS's `person_token_endpoint`. A person token identifies the person the agent acts for to one resource. A resource MUST have verified one before it issues a resource token, and the agent MUST present one on every authorization endpoint request.\n\n```ts\nimport { requestPersonToken } from '@aauth/agent'\n\nconst { personToken, expiresIn } = await requestPersonToken({\n  signedFetch: psSignedFetch,          // createSignedFetch(..., { signBody: true })\n  personServerUrl: 'https://ps.example',\n  resource: 'https://resource.example',\n  missionS256: '...',                  // optional\n  subagentToken: '...',                // optional — parent requesting for a sub-agent\n  onInteraction: (url, code) => { /* the PS may ask the person first */ },\n})\n```\n\nThe request is a signed POST presenting the agent token via `Signature-Key: sig=jwt;jwt=\"…\"`, with body `{resource, mission_s256?, subagent_token?}`. A `202` with `requirement=interaction` is polled at its `Location` like any other deferred response. Call chaining: pass `upstreamToken` (the person or auth token an upstream agent presented to you) and the body carries `upstream_token` in place of `mission_s256`; the PS issues the token for `resource` without a consent card.\n\nPresent the token in place of the agent token:\n\n```http\nSignature-Key: sig=jwt;jwt=\"<person token>\"\n```\n\n### `createPersonTokenCache(options): PersonTokenCache`\n\nCaches person tokens per `(resource, mission_s256)` — a person token is scoped to one resource and, when it carries `mission_s256`, to one mission.\n\n```ts\nimport { createPersonTokenCache } from '@aauth/agent'\n\nconst personTokens = createPersonTokenCache({\n  signedFetch: psSignedFetch,\n  personServerUrl: 'https://ps.example',\n})\n\nconst token = await personTokens.get('https://resource.example', missionS256)\n\n// One rotation of the agent's signing key invalidates every cached token at\n// once — they all bind that key through `cnf`. Flush and re-request lazily.\npersonTokens.clear()\n```\n\n`set(resource, missionS256, token, expiresIn)` seeds a token obtained elsewhere, such as the `person_tokens` map a PS returns with a mission approval.\n\n### `createSignedFetch(getKeyMaterial, options?): FetchLike`\n\nCreates a fetch that signs requests with HTTP Message Signatures but does not handle AAuth challenges. Use this when you only need request signing.\n\n```ts\nimport { createSignedFetch } from '@aauth/agent'\n\nconst signedFetch = createSignedFetch(async () => ({\n  signingKey: privateKeyJwk,\n  signatureKey: { type: 'hwk' }\n}), {\n  capabilities: ['interaction'],\n})\n\n// For PS and AS endpoints: a request carrying a body additionally signs\n// `content-digest` and `content-type`.\nconst psSignedFetch = createSignedFetch(getKeyMaterial, { signBody: true })\n```\n\nSet `signBody` only for PS and AS endpoints. Resources declare what they need through `additional_signature_components` in their metadata, so a blanket body mandate toward a resource would be wrong.\n\n### `exchangeToken(options): Promise<TokenExchangeResult>`\n\nExchanges a resource token for an auth token at the person server. Handles metadata discovery (`/.well-known/aauth-person.json`), 202 deferred responses, and interaction polling.\n\n```ts\nimport { exchangeToken } from '@aauth/agent'\n\nconst { authToken, expiresIn } = await exchangeToken({\n  signedFetch: psSignedFetch,\n  authServerUrl: 'https://ps.example',\n  resourceToken: '...',\n  justification: 'Read project files',\n})\n```\n\n`presentedToken` is REQUIRED (AAuth -11, issue #152): the token the agent presented to the resource that issued the resource token — the person token on the first challenge of a grant, or the auth token on a step-up or per-call challenge. The resource token's `presented_jti` names it; `exchangeToken` checks that binding before sending, and the PS verifies the token against the resource token (and, in four-party access, passes it to the AS). Its `exp` bounds the auth token issued. `createAAuthFetch` supplies it automatically: the person token it presented, or the cached auth token that drew a step-up challenge.\n\nA `clock_skew` refusal (AAuth -11 §Expiry and the Refresh Margin) means the presented token's `iat` is further ahead of the server's clock than its window. A fresh token from the same issuer carries the same skew, so do not refresh: `TokenExchangeError.retryAfterSeconds`, computed from the server's `Date` header, says how long to wait before presenting the same token again. `createAAuthFetch` returns such a `401` from a resource unchanged and keeps its cached token.\n\nThe auth token request has no mission parameter — the mission reaches the PS inside the resource token, which copied it from the person token.\n\n### `fetchAuthServerMetadata(options)` / `resolveAuthServerMetadata(options)`\n\nFetches and validates `/.well-known/aauth-person.json`. Both `auth_token_endpoint` (renamed from `token_endpoint` in -11) and `person_token_endpoint` (new in -11) are REQUIRED; a person server publishing neither cannot complete a flow, and the document is rejected. `resolveAuthServerMetadata` returns a caller-supplied cached copy when there is one.\n\n### `pollDeferred(options): Promise<DeferredResult>`\n\nPolls a 202 Location URL until a terminal response. Handles `Retry-After`, `Prefer: wait`, clarification chat, and interaction codes.\n\n```ts\nimport { pollDeferred } from '@aauth/agent'\n\nconst { response, error } = await pollDeferred({\n  signedFetch,\n  locationUrl: 'https://ps.example/pending/abc123',\n  interactionCode: 'ABCD1234',\n  onInteraction: (url, code) => { /* show to user */ },\n  maxPollDuration: 900, // seconds, default 900\n})\n```\n\n## Protocol primitives\n\nHeader parsing (`parseRequirementHeader`, `buildCapabilitiesHeader`, …), `access_mode` planning, token `typ` and `dwk` constants, and JWT decoding live in [`@aauth/protocol`](../protocol). This package consumes them and defines none of them.\n\n## Key Material Callback\n\nAll signing functions take a `GetKeyMaterial` callback. This decouples key management from the protocol — you provide keys however you want:\n\n```ts\ntype GetKeyMaterial = () => Promise<{\n  signingKey: JsonWebKey          // Ed25519 private key for HTTP signatures\n  signatureKey:\n    | { type: 'jwt', jwt: string }  // agent, person, or auth token\n    | { type: 'hwk' }               // bare public key (pseudonym)\n}>\n```\n\nFor local development, use [`@aauth/local-keys`](../local-keys) to provide this callback from the OS keychain.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}