{"_id":"@aauth/resource","_rev":"8-ee861a420bd9ae4cce86fcade08e6f01","name":"@aauth/resource","dist-tags":{"latest":"3.0.0"},"versions":{"2.0.0":{"name":"@aauth/resource","version":"2.0.0","keywords":["aauth","resource","r3","authorization"],"author":{"name":"Dick Hardt","email":"dick.hardt@hello.coop"},"license":"MIT","_id":"@aauth/resource@2.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":"be2b2a380caab920b79a944d7cbc187dbc705a19","tarball":"https://registry.npmjs.org/@aauth/resource/-/resource-2.0.0.tgz","fileCount":42,"integrity":"sha512-OFSXO26PdieOvZur+mMYmRjWu0+u+R+aaHNfVb30hekXZMxvn9XlyupBA0m+VGNz7b+FDMEFDbmy0rgcbzMKDQ==","signatures":[{"sig":"MEUCIDHYp4cRasFCzzhWo+s8N8nkiOOgVGh8t8ZcDNK71+6YAiEAjZMy5RQK4gUgVwRSWbRmT1K16GsKQ9dwB0NEivH20E8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":139272},"type":"module","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"scripts":{"test":"vitest run","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":"resource"},"_npmVersion":"11.16.0","description":"AAuth resource-side reference implementation: token verification, resource tokens, R3 documents and per-call proposals, challenge headers, interaction management","directories":{},"_nodeVersion":"22.22.3","dependencies":{"jose":"^6.0.0","@aauth/protocol":"^1.0.0","@aauth/interaction-code":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.0.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/resource_2.0.0_1786635774619_0.7745613164918923","host":"s3://npm-registry-packages-npm-production"}},"2.0.1":{"name":"@aauth/resource","version":"2.0.1","keywords":["aauth","resource","r3","authorization"],"author":{"name":"Dick Hardt","email":"dick.hardt@hello.coop"},"license":"MIT","_id":"@aauth/resource@2.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":"921fc2350aa3b42feb09f90d3f34eafb8db91fc8","tarball":"https://registry.npmjs.org/@aauth/resource/-/resource-2.0.1.tgz","fileCount":42,"integrity":"sha512-rm21gtMN+T7hiUyf93B7Eq9LMiHaEilBBK+yHr5Em1g1Rv1oWmXVOvlNZuejIpnyy1ysj8anB4AznShM/ViJeQ==","signatures":[{"sig":"MEQCIAfyrCCcktGHjzbpGXGlYVqztbb0+ZkQkjfHDtNjOy3RAiA6/85WBu/xZIcAJzL0063CxfOmv4a2eNorQtxpOHBWBw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aauth%2fresource@2.0.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":139272},"type":"module","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"8998c7250424a6505b154f5ce22638df7db030e6","scripts":{"test":"vitest run","build":"tsc","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e22f5b26-27a5-4f54-b571-24b184786aa2"}},"repository":{"url":"git+https://github.com/aauth-dev/packages-js.git","type":"git","directory":"resource"},"_npmVersion":"11.17.0","description":"AAuth resource-side reference implementation: token verification, resource tokens, R3 documents and per-call proposals, challenge headers, interaction management","directories":{},"_nodeVersion":"24.19.0","dependencies":{"jose":"^6.0.0","@aauth/protocol":"^1.0.0","@aauth/interaction-code":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.0.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/resource_2.0.1_1786706026738_0.610136288272954","host":"s3://npm-registry-packages-npm-production"}},"2.1.0":{"name":"@aauth/resource","version":"2.1.0","keywords":["aauth","resource","r3","authorization"],"author":{"name":"Dick Hardt","email":"dick.hardt@hello.coop"},"license":"MIT","_id":"@aauth/resource@2.1.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":"7493f87e2da601dd05d9c11e79282ba3e1f0ec93","tarball":"https://registry.npmjs.org/@aauth/resource/-/resource-2.1.0.tgz","fileCount":42,"integrity":"sha512-FKFH835qFWJiTeUD46j7obLZ726+eCROVPGHtUb5Nq8mdxnijYMibgi82CQU3pwfpslgSGS7VFmKZUk9RHZ0hw==","signatures":[{"sig":"MEUCIQCUfhj9JB6V2B+HEOZkTYlsgESb+SI8eMlqdERB+4CIfgIgXERn9l0KNAA3ecQyaoSRO8uAxrcfvgkvE9unL/t6Q8Y=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aauth%2fresource@2.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":140003},"type":"module","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"7bd31a502904272267812e2cd26c231d0f950555","scripts":{"test":"vitest run","build":"tsc","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e22f5b26-27a5-4f54-b571-24b184786aa2"}},"repository":{"url":"git+https://github.com/aauth-dev/packages-js.git","type":"git","directory":"resource"},"_npmVersion":"11.17.0","description":"AAuth resource-side reference implementation: token verification, resource tokens, R3 documents and per-call proposals, challenge headers, interaction management","directories":{},"_nodeVersion":"24.19.0","dependencies":{"jose":"^6.0.0","@aauth/protocol":"^1.0.0","@aauth/interaction-code":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.0.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/resource_2.1.0_1788296162717_0.6245055902329957","host":"s3://npm-registry-packages-npm-production"}},"2.2.0":{"name":"@aauth/resource","version":"2.2.0","keywords":["aauth","resource","r3","authorization"],"author":{"name":"Dick Hardt","email":"dick.hardt@hello.coop"},"license":"MIT","_id":"@aauth/resource@2.2.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":"61dea900c844cbb09d19710be4042475eedf5715","tarball":"https://registry.npmjs.org/@aauth/resource/-/resource-2.2.0.tgz","fileCount":42,"integrity":"sha512-PXP0ff6HpGBrkmdegSBCbjety6aRpKOdhlr9Srb4r5NxXuLtx2QKBlv9ieK26jznMzNFp8ImfbjzyZYN254iEA==","signatures":[{"sig":"MEQCIGrmJw/mOz8QBrRvdCu9FpmvodyQVOuvwbSeA5KJWZTaAiAUckp+kqp+tTPm3IuaLvljxRQP9YXFpzX9e/MpKeoHIQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aauth%2fresource@2.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":143647},"type":"module","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"cd3d9d817a2cbedbd5a59f438e5644eb60093091","scripts":{"test":"vitest run","build":"tsc","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e22f5b26-27a5-4f54-b571-24b184786aa2"}},"repository":{"url":"git+https://github.com/aauth-dev/packages-js.git","type":"git","directory":"resource"},"_npmVersion":"11.19.0","description":"AAuth resource-side reference implementation: token verification, resource tokens, R3 documents and per-call proposals, challenge headers, interaction management","directories":{},"_nodeVersion":"24.20.0","dependencies":{"jose":"^6.0.0","@aauth/protocol":"^1.0.0","@aauth/interaction-code":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.0.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/resource_2.2.0_1788790735879_0.08596783059697644","host":"s3://npm-registry-packages-npm-production"}},"2.3.0":{"name":"@aauth/resource","version":"2.3.0","keywords":["aauth","resource","r3","authorization"],"author":{"name":"Dick Hardt","email":"dick.hardt@hello.coop"},"license":"MIT","_id":"@aauth/resource@2.3.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":"1317415e979b480037c32b687773fa0b985e0503","tarball":"https://registry.npmjs.org/@aauth/resource/-/resource-2.3.0.tgz","fileCount":46,"integrity":"sha512-Sm9bWdUWQD2kZtMnhAHxYhZ0qfjnaajncuPGKxmY2DFJnmXaCgudZj0ZWZ1JSR6lL9j6sZcYJNINrST5fAXChw==","signatures":[{"sig":"MEQCIA231IYaM2XUvDZhzNBIxd+m1JZAt+D99XHhBD0WapzQAiACPEcESKx+YquWQJxHLecTNXEnZS6p3FyAdB9izZq45g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aauth%2fresource@2.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":170380},"type":"module","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"c9190130f68233727a1f2732e01b848f5fd4e0e2","scripts":{"test":"vitest run","build":"tsc","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e22f5b26-27a5-4f54-b571-24b184786aa2"}},"repository":{"url":"git+https://github.com/aauth-dev/packages-js.git","type":"git","directory":"resource"},"_npmVersion":"11.19.0","description":"AAuth resource-side reference implementation: token verification, resource tokens, R3 documents and per-call proposals, challenge headers, interaction management","directories":{},"_nodeVersion":"24.20.0","dependencies":{"jose":"^6.0.0","@aauth/protocol":"^1.0.0","@aauth/interaction-code":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.0.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/resource_2.3.0_1788813984364_0.09622344106711966","host":"s3://npm-registry-packages-npm-production"}},"2.4.0":{"name":"@aauth/resource","version":"2.4.0","keywords":["aauth","resource","r3","authorization"],"author":{"name":"Dick Hardt","email":"dick.hardt@hello.coop"},"license":"MIT","_id":"@aauth/resource@2.4.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":"eef208e96b65d4a1b0d2b084e60b0a3bb4eca28e","tarball":"https://registry.npmjs.org/@aauth/resource/-/resource-2.4.0.tgz","fileCount":46,"integrity":"sha512-zOjuqUNqU9qGf+dalXA8Rb6YQ3WkSZI0n2DD47h86r34C7q4pl8CNQIuVBD3C+rJZ0TTyqFtaSKJfb7uPjKVKQ==","signatures":[{"sig":"MEUCIHv/qi836Qb6xJB0sM+D7b85uzb7jXCE+n/ts5Ba4LVFAiEA1ulc3jptWD79DffAi5KD8QZeMvvK5yA85+Fq45fYDro=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aauth%2fresource@2.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":172806},"type":"module","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"3cc28305a135345d0e55b897f2e142b6f8e77a0a","scripts":{"test":"vitest run","build":"tsc","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e22f5b26-27a5-4f54-b571-24b184786aa2"}},"repository":{"url":"git+https://github.com/aauth-dev/packages-js.git","type":"git","directory":"resource"},"_npmVersion":"11.19.0","description":"AAuth resource-side reference implementation: token verification, resource tokens, R3 documents and per-call proposals, challenge headers, interaction management","directories":{},"_nodeVersion":"24.20.0","dependencies":{"jose":"^6.0.0","@aauth/protocol":"^1.0.0","@aauth/interaction-code":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.0.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/resource_2.4.0_1788873277052_0.3755362936834319","host":"s3://npm-registry-packages-npm-production"}},"2.5.0":{"name":"@aauth/resource","version":"2.5.0","keywords":["aauth","resource","r3","authorization"],"author":{"name":"Dick Hardt","email":"dick.hardt@hello.coop"},"license":"MIT","_id":"@aauth/resource@2.5.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":"50ea50cf3908a7fa7182a5b8812c5e47a85cbd7c","tarball":"https://registry.npmjs.org/@aauth/resource/-/resource-2.5.0.tgz","fileCount":46,"integrity":"sha512-adoELzZa580cxpl9Saeqv15NkJMB6YAqFuuNhAJ+n9TXpdVIjNu6r7PpeNxb+OG8clhjQmqsq9rYR/x+N3OYWA==","signatures":[{"sig":"MEYCIQDDXDFAUMdC9UBm8VtYfAG5xN+7h+75LllLNhPRrDrqZgIhAL/NhBeolK6wYbzmbUPeYG6Mqm0U07xQXmg+QpKUNfjg","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aauth%2fresource@2.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":175021},"type":"module","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"gitHead":"b19dd7d45d98b6a57b9ed469796f2beba9aa72bf","scripts":{"test":"vitest run","build":"tsc","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e22f5b26-27a5-4f54-b571-24b184786aa2"}},"repository":{"url":"git+https://github.com/aauth-dev/packages-js.git","type":"git","directory":"resource"},"_npmVersion":"11.19.0","description":"AAuth resource-side reference implementation: token verification, resource tokens, R3 documents and per-call proposals, challenge headers, interaction management","directories":{},"_nodeVersion":"24.20.0","dependencies":{"jose":"^6.0.0","@aauth/protocol":"^1.0.0","@aauth/interaction-code":"^0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.0.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/resource_2.5.0_1788876628190_0.17788409838931085","host":"s3://npm-registry-packages-npm-production"}},"3.0.0":{"name":"@aauth/resource","version":"3.0.0","description":"AAuth resource-side reference implementation: token verification, resource tokens, R3 documents and per-call proposals, challenge headers, interaction management","type":"module","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"}},"scripts":{"build":"tsc","test":"vitest run","prepublishOnly":"npm run build"},"keywords":["aauth","resource","r3","authorization"],"author":{"name":"Dick Hardt","email":"dick.hardt@hello.coop"},"license":"MIT","publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/aauth-dev/packages-js.git","directory":"resource"},"dependencies":{"@aauth/interaction-code":"^0.1.0","@aauth/protocol":"^2.0.0","jose":"^6.0.0"},"devDependencies":{"@types/node":"^20.0.0","typescript":"^5.0.0"},"gitHead":"381ad53efd36fe709ca36d496a62bba5dba1610f","_id":"@aauth/resource@3.0.0","bugs":{"url":"https://github.com/aauth-dev/packages-js/issues"},"homepage":"https://github.com/aauth-dev/packages-js#readme","_nodeVersion":"22.22.3","_npmVersion":"11.16.0","dist":{"integrity":"sha512-M5AVghZJhoEgxi5/xVdTlGEvD8hXT+/0PJQ1wylRLqFqTiJdf1VEJZEFHAT8aGMFrxB/rKmMx+nVa7xOZhCepw==","shasum":"125de439c7e6060c3d645f9f8c0b993e2209cd75","tarball":"https://registry.npmjs.org/@aauth/resource/-/resource-3.0.0.tgz","fileCount":46,"unpackedSize":179047,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIGnMRu78z1xH9eIw2FXiQUXnBXHMlNcmn5XF6BXU7VaWAiEAug7/meAi/gv8A9gD5aj/VAc1+PHe1Jp0h3Ixs1Tmw30="}]},"_npmUser":{"name":"dickhardt","email":"dickhardt@gmail.com"},"directories":{},"maintainers":[{"name":"dickhardt","email":"dickhardt@gmail.com"},{"name":"rohanharikr","email":"rohanharikumar80@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/resource_3.0.0_1788940560229_0.9448038769648084"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-13T15:42:54.453Z","modified":"2026-09-09T07:56:00.739Z","2.0.0":"2026-08-13T15:42:54.794Z","2.0.1":"2026-08-14T11:13:46.878Z","2.1.0":"2026-09-01T20:56:02.888Z","2.2.0":"2026-09-07T14:18:55.998Z","2.3.0":"2026-09-07T20:46:24.486Z","2.4.0":"2026-09-08T13:14:37.167Z","2.5.0":"2026-09-08T14:10:28.327Z","3.0.0":"2026-09-09T07:56:00.397Z"},"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","resource","r3","authorization"],"repository":{"type":"git","url":"git+https://github.com/aauth-dev/packages-js.git","directory":"resource"},"description":"AAuth resource-side reference implementation: token verification, resource tokens, R3 documents and per-call proposals, challenge headers, interaction management","maintainers":[{"name":"dickhardt","email":"dickhardt@gmail.com"},{"name":"rohanharikr","email":"rohanharikumar80@gmail.com"}],"readme":"# @aauth/resource\n\nThe resource-side reference implementation of [AAuth](https://github.com/dickhardt/AAuth). Verify\nwhat an agent presents, mint what a resource issues, publish and enforce R3.\n\nFormerly `@aauth/mcp-server`. It contains no MCP and never did — it is the library a resource uses,\nwhatever protocol the resource speaks.\n\nRuns on Cloudflare Workers. This package imports no `node:*` built-ins; it uses only `crypto`,\n`crypto.subtle`, `fetch`, `TextEncoder` and `TextDecoder`.\n\nHeader construction and parsing live in [`@aauth/protocol`](https://www.npmjs.com/package/@aauth/protocol)\nand are re-exported here, so a resource has one import.\n\n## Install\n\n```bash\nnpm install @aauth/resource\n```\n\n## Verifying what the agent presented\n\n```ts\nimport { verifyToken, AAuthTokenError } from '@aauth/resource'\n\nconst verified = await verifyToken({\n  jwt: sig.jwt.raw,                       // from @hellocoop/httpsig\n  httpSignatureThumbprint: sig.thumbprint,\n  resource: 'https://notes.example',      // this resource's own identifier\n  accept: ['auth'],                       // what THIS endpoint requires\n})\n```\n\n`accept` is required and there is no default. A person token and a PS-issued auth token carry the\nsame `iss`, `dwk`, `aud`, `sub` and `cnf`; only `typ` distinguishes them. An endpoint that requires\nauthorization passes `['auth']`. Passing `['auth', 'person']` there accepts an identity assertion as\na grant, and the mistake fails open — so the check is a parameter you must state, not one you can\nforget.\n\n`verifyToken` performs: `typ` recognition → the `accept` check → required-claim structure → `exp`\nin the future and `iat` not in the future → key binding (`cnf.jwk` against the HTTP signing key) →\n`kid` selection and signature verification against the JWKS discovered at `{iss}/.well-known/{dwk}`\n→ `iss` a valid HTTPS server identifier → `aud` equal to `resource` → the revocation list, when one\nis supplied (see [Revocation](#revocation)). Nothing is acted on before the signature verifies.\n\nThe polymorphic `EdDSA` identifier is rejected in both the JWT header and `cnf.jwk`, per RFC 9864.\n\n### Results\n\n| `type` | Shape |\n| --- | --- |\n| `'agent'` | `iss`, `sub`, `jti?`, `ps?`, `parent_agent?`, `cnf`, `iat`, `exp`, `claims` |\n| `'person'` | `iss`, `aud`, `sub`, `jti`, `mission_s256?`, `tenant?`, `cnf`, `iat`, `exp`, `claims` |\n| `'auth'` | `iss`, `aud`, `ps`, `sub`, `scope?`, `account?`, `mission_s256?`, `tenant?`, `r3_uri?`, `r3_s256?`, `r3_granted?`, `r3_per_call?`, `cnf`, `iat`, `exp`, `claims` |\n\nThere is no `agent` claim in AAuth -11 and none is surfaced. A resource learns which agent it is\ntalking to from the agent token, and binds authorization to the key via `agent_jkt` / `cnf`.\n\n`sub` is unique within the issuer, not globally. Treat `(iss, sub)` as the identity, treat `sub` as\nopaque, and never match a `sub` from one issuer against a record established under another, however\nthe values compare.\n\n### Errors\n\n`AAuthTokenError` carries a stable `code`. Branch on `code`, never on `message`.\n\n| Code | Meaning |\n| --- | --- |\n| `unsupported_token_type` | `typ` is not an AAuth token type |\n| `token_type_not_accepted` | Recognized, but not allowed at this call site — including a person token where an auth token is required |\n| `invalid_agent_token` / `invalid_person_token` / `invalid_auth_token` | Structure, discovery or signature failed |\n| `token_expired` | `exp` is in the past by this verifier's clock, with no tolerance, on a token whose issuer signature verified |\n| `clock_skew` | `iat` is further ahead of this verifier's clock than `clockToleranceSeconds` (default 60). The issuer's clock, not the token, is at fault: a fresh token carries the same skew, so the presenter waits the difference out (the response `Date` header is the verifier's clock). Answer `401` with `Signature-Error: error=clock_skew` |\n| `aud_mismatch` | `aud` is not this resource |\n| `key_binding_failed` | `cnf.jwk` is not the key that signed the request |\n| `revoked_jwt` | The issuer revoked this token (`revocation` was supplied and holds its `(iss, jti)`). Answer `401` with `Signature-Error: error=revoked_jwt` |\n| `metadata_fetch_failed` | `{iss}/.well-known/{dwk}` could not be read |\n| `invalid_configuration` | `accept` or `resource` was not supplied correctly |\n\n**Order matters, and expiry comes late.** Structural checks that need no\nauthentication run first — a claim absent or of the wrong type says the bytes\nare not a well-formed AAuth token, whoever wrote them. Everything that\ninterprets a claim's *value* runs after the issuer's signature verifies,\n`exp` included.\n\nThat is why a token that was both edited and expired reports\n`invalid_person_token` (signature verification failed) rather than\n`token_expired`. `token_expired` tells a caller to go and get a fresh token;\na forgery reporting it would send the caller off to refresh a token that was\nnever the problem. Changed in 2.2.0 — earlier versions checked `exp` before\nresolving the issuer's JWKS.\n\n**Changed in 2.4.0.** `exp` is judged against this verifier's clock with no\ntolerance, per AAuth -11 §Expiry and the Refresh Margin: the agent refreshes\nat least five minutes before expiry, and a verifier that allowed for skew on\n`exp` would only let a token that one hop accepted fail at the next.\n`clockToleranceSeconds` now bounds `iat` alone, and an `iat` beyond it is\n`clock_skew` rather than `invalid_*_token`.\n\n## Challenging\n\n```ts\nimport { buildAAuthHeader } from '@aauth/resource'\n\nbuildAAuthHeader('agent-token')    // 401 — present your agent token\nbuildAAuthHeader('person-token')   // 401 — obtain a person token from your PS and retry\nbuildAAuthHeader('auth-token', { resourceToken })\nbuildAAuthHeader('interaction', { code })        // 202 — the agent composes {interaction_endpoint}?code=\nbuildAAuthHeader('approval')\nbuildAAuthHeader('clarification')\nbuildAAuthHeader('claims')\n```\n\nA resource MUST have verified a person token before it issues a resource token, and MUST challenge\nwith `requirement=person-token` when it has not.\n\n`buildMissionHeader`, `parseMissionHeader` and the `AAuthMission` type are gone. The `AAuth-Mission`\nheader and its IANA registration were removed in -11. A mission reaches a resource only inside a\nPS-issued token, as `mission_s256`.\n\n## Minting a resource token\n\n```ts\nimport { createResourceToken } from '@aauth/resource'\n\nconst resourceToken = await createResourceToken(\n  {\n    resource: 'https://notes.example',   // iss\n    audience: psUrl,                     // aud: the PS (three-party) or the AS (four-party)\n    presentedToken: verifiedToken,       // the person token, or on a step-up the auth token, the\n                                         // request carried: ps, sub, presented_jti, mission_s256,\n                                         // tenant come from here\n    agentJkt: sig.thumbprint,\n    scope: 'notes.read notes.write',\n    kid: publicJwk.kid,\n    r3: { uri: r3_uri, s256: r3_s256 },  // optional; both or neither\n    interactionCode,                     // optional: the resource's own flow must run first\n    missionExpiresAt,                    // optional clamp\n  },\n  async (payload, header) => signJwt(header, payload, privateKey),\n)\n```\n\n`scope` present means the PS will issue an auth token once its own consent is done. A\n**connection-only** token — the answer to `POST /connections`, which asks the PS to drive the\nresource's upstream OAuth and nothing else — carries `interaction_code` and no `scope`, so the PS\nterminates the poll with `connection_established` instead of issuing:\n\n```ts\nawait createResourceToken(\n  { resource, audience, presentedToken, agentJkt, kid, connectionOnly: true, interactionCode, account },\n  sign,\n)\n```\n\n`interactionCode` is emitted as the flat `interaction_code` claim; the PS composes\n`{interaction_endpoint}?code=…` from the resource's published metadata. The nested\n`interaction: { url, code }` claim of 2.x is gone (3.0.0).\n\nThe header handed to your signer is `{ alg: 'Ed25519', typ: 'aa-resource+jwt', kid? }`. Sign it as\ngiven — `alg` is the fully-specified RFC 9864 identifier, and the polymorphic `EdDSA` MUST NOT be\nused.\n\n`presentedToken` is whatever `verifyToken` returned for the request being challenged: a\n`VerifiedPersonToken` on the first challenge of a grant, a `VerifiedAuthToken` on a step-up or\nper-call challenge (AAuth -11, issue #152). `ps` is a person token's `iss` or an auth token's `ps`;\n`presented_jti` is that token's `jti`. The agent hands the same token to its PS as `presented_token`,\nand the PS (and in four-party the AS) verifies it against the resource token — so a resource keeps\nno record of what it verified. `personToken` is accepted as a deprecated alias.\n\n`mission_s256` is copied from the presented token unchanged and is REQUIRED when that token carried\none; a resource MUST NOT omit it. The PS compares the presented token to the resource token, so\ndropping it is detected as mission stripping.\n\n`presented_jti` is the claim's name since spec issue #95; the token also carries the deprecated\npre-rename alias `person_token_jti` with the same value, so a PS that has not picked up the rename\nkeeps working. The alias will be dropped once the transition ends.\n\n`clampToMission(exp, missionExpiresAt)` is exported for anything else a resource derives from a\nmission-scoped token: no token carrying `mission_s256` may outlive its mission.\n\n## R3 documents\n\n```ts\nimport { publishR3Document, serveR3Document } from '@aauth/resource'\n\nconst { r3_uri, r3_s256 } = await publishR3Document({\n  document: {\n    vocabulary: 'urn:aauth:vocabulary:mcp',\n    operations: [{ tool: 'create_note' }],\n    display: { summary: 'Create notes in your notebook' },\n  },\n  baseUri: 'https://notes.example/r3',\n  store,\n  authorized: [psUrl, agentToken.ps],   // see below\n})\n```\n\n**Serialize once, serve those exact bytes.** `r3_s256` is the SHA-256 of the bytes as served, with\nno canonicalization step. Any re-stringify — middleware that parses and re-encodes JSON, a framework\n`json()` helper, CDN minification, key reordering — changes the bytes and breaks hash verification at\nthe PS and AS. `publishR3Document` serializes once and stores the result; `serveR3Document` returns\nthose bytes verbatim. Write the returned `body` to the wire as-is; do not pass it through a JSON\nresponse helper.\n\nR3 -02 removed the `version` field. Including one is rejected.\n\n### The store you supply\n\n```ts\ninterface R3Store {\n  get(key: string): Promise<R3Record | null>\n  put(key: string, record: R3Record, ttlSeconds?: number): Promise<void>\n}\n\ninterface R3Record {\n  uri: string          // the r3_uri this is served at\n  s256: string         // BASE64URL(SHA-256(body)) — the r3_s256 claim\n  body: string         // the exact bytes to serve\n  authorized: string[] // server identifiers entitled to fetch it\n  createdAt: number\n  expiresAt?: number\n}\n```\n\nTwo methods, both keyed by opaque string. Back it with Workers KV\n(`put(key, JSON.stringify(record), { expirationTtl })` / `get(key, 'json')`), Redis, or anything\nelse — `body` is a string and survives a JSON round trip unchanged. `MemoryR3Store` is a conforming\nin-memory implementation for tests and single-process deployments.\n\nEach record is written under two keys: its `s256` and its `uri`. The fetch path knows only the URI;\nthe per-call retry path knows only the hash from the auth token. Both resolve.\n\n### Access restriction\n\nAgents must never read an R3 document — agent opacity depends entirely on it. Exactly two parties\nare entitled:\n\n- the AS named in the `aud` of a resource token carrying that `r3_uri`; and\n- the PS named by the `ps` claim of the agent token the agent presented.\n\nPass both to `publishR3Document` as `authorized`. In three-party access they are the same party.\n\n```ts\nconst res = await serveR3Document({ store, key: url.pathname.split('/').pop()!, signer })\n// 401 unsigned · 403 wrong signer · 404 unknown · 200 with the exact stored bytes\n```\n\n`signer` is the server identifier established from the *verified* HTTP Message Signature on the\nfetch — not a header the caller controls. Comparison is exact string equality.\n\n## Per-call proposals\n\nAn `r3_per_call` operation is authorized in principle but not for any specific call. When the agent\ninvokes one, build a proposal: a full R3 document scoped to that one invocation, carrying a REQUIRED\n`parameters` object.\n\n```ts\nimport { publishProposal, digestParameter, verifyProposalParameters } from '@aauth/resource'\n\n// 1. Challenge\nconst proposal = await publishProposal({\n  vocabulary: 'urn:aauth:vocabulary:mcp',\n  operation: { tool: 'send_email' },\n  parameters: {\n    to: 'mom@example.com',\n    subject: 'Dinner Sunday?',\n    body: await digestParameter(emailBody, { media_type: 'text/plain' }),\n  },\n  display: { summary: 'Send an email as you', detail: '## Action\\nSend an email\\n\\n## To\\nmom@example.com' },\n  store,\n  baseUri: 'https://mail.example/r3',\n  authorized: [asUrl, agentToken.ps],\n})\n// mint a resource token with r3: { uri: proposal.r3_uri, s256: proposal.r3_s256 }\n\n// 2. …the AS evaluates the parameters, the PS renders `display`, the agent retries…\n\n// 3. Enforced retry\nawait verifyProposalParameters({\n  store,\n  r3_s256: authToken.r3_s256!,\n  presented: call.arguments,\n  operation: { tool: 'send_email' },\n})\n```\n\n`verifyProposalParameters` rejects on any difference: a parameter the proposal did not carry, an\napproved parameter missing from the call, a structural value that does not deep-equal the approved\none, or a digest parameter whose bytes do not satisfy `BASE64URL(SHA-256(presented)) === s256`. An\napproval to email one recipient cannot be replayed against another.\n\n`digestParameter` keeps a large or sensitive value out of every token and away from the PS: only the\nhash and a short excerpt appear in the proposal. The full bytes travel agent → resource at call\ntime, where they are verified against the digest.\n\nThe token carries only `r3_uri` / `r3_s256`, never the parameters.\n\n## Revocation\n\nA resource verifies tokens statelessly, so nothing in `verifyToken`'s path reports that an issuer\nwithdrew a token. Revocation is the one piece of state a resource keeps: the `(iss, jti)` pairs an\nissuer has told it about, each held until the token's own `exp` (AAuth Protocol §Token Revocation).\n\n```ts\nimport { KVRevocationStore, MemoryRevocationStore, handleRevocation, DWK } from '@aauth/resource'\n\nconst revocation = new KVRevocationStore(env.TOKENS)   // or new MemoryRevocationStore() on one Node process\n\n// Every verifyToken call site passes the list; a revoked token throws code `revoked_jwt`.\nawait verifyToken({ jwt, httpSignatureThumbprint, resource, accept: ['auth'], revocation })\n\n// POST /aauth/revoke — the caller signed as a server (Signature-Key sig=jwks_uri), which\n// the resource verified with @hellocoop/httpsig; `id` and `dwk` come off that result.\napp.post('/aauth/revoke', async (c) => {\n  const sig = await verify(...)                          // @hellocoop/httpsig\n  if (sig.keyType !== 'jwks_uri') return unsupportedScheme(['jwks_uri'])\n  return handleRevocation(c.req.raw, { id: sig.jwks_uri.id, dwk: sig.jwks_uri.dwk }, {\n    store: revocation,\n    issuers: ['https://ps.example', 'https://as.example'],   // the servers you exchange tokens with\n  })\n})\n```\n\nAdvertise the endpoint as `revocation_endpoint` in `aauth-resource.json`.\n\nThe request body is `{ \"jti\", \"exp\" }`, both REQUIRED. The issuer is never a parameter: the store\nis keyed by the **verified caller**, so a caller can only revoke its own tokens — revoking another\nissuer's is unreachable, not refused. `handleRevocation` answers `200 OK` with an empty body once\nrecorded, whether or not the resource ever saw the token (there is no \"not found\"); `400\ninvalid_request` for a malformed body, or an `exp` further out than `maxLifetimeSeconds` (default\n24 h); `403 unsupported_iss` for a caller not in `issuers` or not signing through\n`aauth-person.json` / `aauth-access.json` (`dwks`). An `exp` already past is `200` with nothing\nwritten. Signature failures — unsigned, unverifiable, or a `jwt`-scheme caller — are the resource's\nto answer with `401` and `Signature-Error` before it reaches this call. `applyRevocation` is the\nsame logic without the `Response`, and `RevocationStore` is the two-method interface behind both\nstores if you keep the list elsewhere.\n\n**Presenting a revoked token.** The token is otherwise sound, so `verifyToken` refuses it last,\nwith `revoked_jwt`, and the resource answers `401` with `Signature-Error: error=revoked_jwt`. For a\nrevoked auth token it SHOULD also carry `AAuth-Requirement: requirement=auth-token` with a fresh\nresource token, so one response says why the token failed and how to recover; a revoked person\ntoken gets `requirement=person-token`, and a revoked agent token no requirement at all.\n\n## Interaction (202 deferred responses)\n\n```ts\nimport { InteractionManager } from '@aauth/resource'\n\nconst manager = new InteractionManager({ baseUrl: 'https://notes.example' })\n\nconst { headers, pending } = manager.createPending()\n// headers: Location, Retry-After, Cache-Control,\n//          AAuth-Requirement: requirement=interaction;code=\"XXXX-XXXX\"\n// The agent composes the URL from the `interaction_endpoint` in your metadata.\n// `interactionUrl` (deprecated) keeps emitting `url=` for 2.x-era recipients.\nmanager.resolve(pending.id, { granted: true })\n```\n\nThis is the only part of the package with a transitive `node:crypto` dependency, via\n`@aauth/interaction-code`. On Workers it needs `nodejs_compat`, which workerd supports.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}