{"_id":"@axiru/x402-policy-middleware","_rev":"2-8931832cb6f9266cc8f887c9101808a9","name":"@axiru/x402-policy-middleware","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@axiru/x402-policy-middleware","version":"0.1.0","keywords":["x402","payments","agentic-payments","governance","policy","stablecoin","usdc","base","axiru"],"author":{"name":"Axiru"},"license":"Apache-2.0","_id":"@axiru/x402-policy-middleware@0.1.0","maintainers":[{"name":"axiru","email":"marcos@axiru.com"}],"homepage":"https://github.com/AxiruAI/axiru-oss/tree/main/packages/x402-policy-middleware#readme","bugs":{"url":"https://github.com/AxiruAI/axiru-oss/issues"},"dist":{"shasum":"5953324655515507c89d47851aace386d85e9f10","tarball":"https://registry.npmjs.org/@axiru/x402-policy-middleware/-/x402-policy-middleware-0.1.0.tgz","fileCount":24,"integrity":"sha512-lT1BTv4S0iiWAN7xL6pCEUpR/vCnYNVeeFwxWlIcX9Vpb8kBkFhuBQyNTBH+mHStEZG/1BQUWjT29WAWlfawtg==","signatures":[{"sig":"MEYCIQDByGhaPKos+RIoWh80R68l9VREpR+oqDamN89b+l/4AwIhAPrgpdPLeR1+tTWnDJ+C+rrcqueJb6/Z5gqQ1XH3dhtn","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":131921},"main":"dist/x402-policy-middleware/src/index.js","type":"module","types":"dist/x402-policy-middleware/src/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/x402-policy-middleware/src/index.d.ts","import":"./dist/x402-policy-middleware/src/index.js"}},"gitHead":"9601ad2c5bda7c27bbf866b78f390fc0f3ee8ee7","private":false,"scripts":{"lint":"tsc --noEmit","test":"pnpm --filter @axiru/spec build && tsc -p tsconfig.json && node dist/x402-policy-middleware/src/middleware.test.js && node dist/x402-policy-middleware/src/ovt-builder.test.js && node dist/x402-policy-middleware/src/error-response.test.js && node dist/x402-policy-middleware/src/governance-extension.test.js && node dist/x402-policy-middleware/src/agent-payment.test.js && node dist/x402-policy-middleware/src/mpp-charge-intent.test.js","build":"tsc -p tsconfig.json","prepack":"pnpm run build","typecheck":"tsc --noEmit"},"_npmUser":{"name":"axiru","email":"marcos@axiru.com"},"repository":{"url":"git+https://github.com/AxiruAI/axiru-oss.git","type":"git","directory":"packages/x402-policy-middleware"},"_npmVersion":"11.8.0","description":"Policy pre-authorization middleware for x402 (HTTP 402 Payment Required) flows. Wraps an x402 facilitator request with a governance decision check and emits a signed authorization token the signer can verify before broadcasting on-chain.","directories":{},"_nodeVersion":"24.13.1","dependencies":{"@axiru/spec":"workspace:*"},"publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.3","@types/node":"^25.9.1"},"_npmOperationalInternal":{"tmp":"tmp/x402-policy-middleware_0.1.0_1785886214806_0.5165850958426665","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@axiru/x402-policy-middleware","version":"0.1.1","description":"Policy pre-authorization middleware for x402 (HTTP 402 Payment Required) flows. Wraps an x402 facilitator request with a governance decision check and emits a signed authorization token the signer can verify before broadcasting on-chain.","license":"Apache-2.0","private":false,"author":{"name":"Axiru"},"homepage":"https://github.com/AxiruAI/axiru-oss/tree/main/packages/x402-policy-middleware#readme","repository":{"type":"git","url":"git+https://github.com/AxiruAI/axiru-oss.git","directory":"packages/x402-policy-middleware"},"bugs":{"url":"https://github.com/AxiruAI/axiru-oss/issues"},"type":"module","main":"dist/x402-policy-middleware/src/index.js","types":"dist/x402-policy-middleware/src/index.d.ts","exports":{".":{"types":"./dist/x402-policy-middleware/src/index.d.ts","import":"./dist/x402-policy-middleware/src/index.js"}},"engines":{"node":">=18"},"scripts":{"build":"tsc -p tsconfig.json","lint":"tsc --noEmit","typecheck":"tsc --noEmit","test":"pnpm --filter @axiru/spec build && tsc -p tsconfig.json && node dist/x402-policy-middleware/src/middleware.test.js && node dist/x402-policy-middleware/src/ovt-builder.test.js && node dist/x402-policy-middleware/src/error-response.test.js && node dist/x402-policy-middleware/src/governance-extension.test.js && node dist/x402-policy-middleware/src/agent-payment.test.js && node dist/x402-policy-middleware/src/mpp-charge-intent.test.js","prepack":"pnpm run build"},"dependencies":{"@axiru/spec":"^0.1.0"},"devDependencies":{"@types/node":"^25.9.1","typescript":"^5.6.3"},"publishConfig":{"access":"public","provenance":true},"keywords":["x402","payments","agentic-payments","governance","policy","stablecoin","usdc","base","axiru"],"gitHead":"a231ab3f691b1d3e0b18ff6f22a5d14ecaaf5cf3","_id":"@axiru/x402-policy-middleware@0.1.1","_nodeVersion":"24.13.1","_npmVersion":"11.8.0","dist":{"integrity":"sha512-IRtkURk+RriI8hKOxZU3plsxeAyX/aBlv5e9EGZ4M8gbJi2gOkWYmrTrgAFa6kWmkkQsJu8C8vv75eI/6DyA+A==","shasum":"6f84f87d4f6c17078961df1fe945758f204d144f","tarball":"https://registry.npmjs.org/@axiru/x402-policy-middleware/-/x402-policy-middleware-0.1.1.tgz","fileCount":24,"unpackedSize":131916,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQD0teDpuACYfpYUY8G4aSZpy7CTZ/MjTW4cBMrbAufiUgIhAPdlEkcEAeMDcYVPNOY4BIlBpY8+0CJM7pAyEAf08WaX"}]},"_npmUser":{"name":"axiru","email":"marcos@axiru.com"},"directories":{},"maintainers":[{"name":"axiru","email":"marcos@axiru.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/x402-policy-middleware_0.1.1_1786468588508_0.00879489523651178"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-04T23:30:14.625Z","modified":"2026-08-11T17:16:28.824Z","0.1.0":"2026-08-04T23:30:14.947Z","0.1.1":"2026-08-11T17:16:28.648Z"},"bugs":{"url":"https://github.com/AxiruAI/axiru-oss/issues"},"author":{"name":"Axiru"},"license":"Apache-2.0","homepage":"https://github.com/AxiruAI/axiru-oss/tree/main/packages/x402-policy-middleware#readme","keywords":["x402","payments","agentic-payments","governance","policy","stablecoin","usdc","base","axiru"],"repository":{"type":"git","url":"git+https://github.com/AxiruAI/axiru-oss.git","directory":"packages/x402-policy-middleware"},"description":"Policy pre-authorization middleware for x402 (HTTP 402 Payment Required) flows. Wraps an x402 facilitator request with a governance decision check and emits a signed authorization token the signer can verify before broadcasting on-chain.","maintainers":[{"name":"axiru","email":"marcos@axiru.com"}],"readme":"# @axiru/x402-policy-middleware\n\nPolicy pre-authorization for [x402](https://www.x402.org/) (HTTP 402 Payment Required) flows. Wraps an x402 facilitator request with a governance decision check and emits a signed authorization token that the signer verifies before it broadcasts on-chain.\n\n**Apache-2.0. Transport agnostic. No I/O of its own.**\n\n## Why\n\nx402 flows skip your fraud, compliance, and approval gates by design. The agent makes an HTTP call, the resource server replies `402 Payment Required`, the agent signs an on-chain transfer, the facilitator broadcasts. There is no merchant of record between the agent and on-chain settlement, and nothing in the protocol asks whether your organization wanted that payment to happen.\n\nThis package sits between the agent and the signer and re-introduces that question:\n\n```\n┌─────────┐  402 Payment Required  ┌─────────────┐\n│  Agent  │ ─────────────────────► │ Facilitator │\n└────┬────┘                        └─────────────┘\n     │\n     │ authorizeX402Request(challenge, context, deps)\n     │\n     ▼\n┌──────────────────────────┐\n│ @axiru/x402-policy-      │── callDecisionEngine ──► your policy decision endpoint\n│   middleware             │\n│                          │── signAuthorizationToken ──► your signer\n└──────────────────────────┘\n     │\n     │ MiddlewareResult { status: \"allowed\" | \"blocked\" | \"internal_error\" }\n     ▼\n   Signer verifies the authorization token, then broadcasts\n   (or fail-closed refuses to broadcast).\n```\n\nThe middleware is transport agnostic, I/O free, and pure beyond its injected dependencies. It runs on Node, Bun, Deno, Cloudflare Workers, or in a Lambda.\n\n## Install\n\n```bash\nnpm install @axiru/x402-policy-middleware\n```\n\nThe only runtime dependency is [`@axiru/spec`](https://www.npmjs.com/package/@axiru/spec), the shared policy and evidence vocabulary.\n\n## Quickstart\n\n```ts\nimport {\n  authorizeX402Request,\n  toHttpResponse,\n  type X402PaymentRequirements,\n  type X402RequestContext,\n  type MiddlewareDependencies,\n} from \"@axiru/x402-policy-middleware\";\n\nconst deps: MiddlewareDependencies = {\n  callDecisionEngine: async (ovt, policyInputs) =>\n    fetch(\"https://policy.example.com/v1/decisions\", {\n      method: \"POST\",\n      body: JSON.stringify({ ovt, policyInputs }),\n    }).then((r) => r.json()),\n\n  signAuthorizationToken: async (claims) =>\n    fetch(\"https://policy.example.com/v1/authorizations\", {\n      method: \"POST\",\n      body: JSON.stringify(claims),\n    }).then((r) => r.text()),\n\n  fingerprintOVT: (ovt) => sha256(canonicalJson(ovt)),\n\n  issuer: \"https://policy.example.com\",\n};\n\n// Inside your agent's x402 handler:\nconst result = await authorizeX402Request(challenge, context, deps);\n\nif (result.status === \"allowed\") {\n  // Retry the facilitator with the authorization token attached:\n  await fetch(challenge.resource_url, {\n    headers: { \"axiru-authorization\": result.authorization_token },\n  });\n} else {\n  // Fail-closed: do NOT broadcast.\n  const http = toHttpResponse(result);\n  return res.status(http.status).json(http.body);\n}\n```\n\n`fingerprintOVT` must be a stable canonical-JSON SHA-256 over the transfer. Any implementation works as long as it is deterministic across processes; the fingerprint is the replay key that ties a decision to the exact transfer it authorized.\n\n## Fail-closed contract\n\nThe middleware never returns `allowed` unless both of the following hold:\n\n1. The decision endpoint explicitly returned `allow`, and\n2. The signer returned a non-empty token string.\n\nEvery other outcome produces a non-`allowed` result: the decision call throws, the signer throws, the signer returns empty, the payload is structurally invalid, or the decision is `deny`, `quarantine`, or `require_approval`. The signer is contractually required to refuse to broadcast on any non-`allowed` result.\n\n## HTTP status mapping\n\n`toHttpResponse` maps results to HTTP wire codes:\n\n| Result                         | Status | Notes                                              |\n| ------------------------------ | -----: | -------------------------------------------------- |\n| `allowed`                      |  `200` | `axiru-authorization` header carries the JWS token |\n| `blocked` (`deny`)             |  `403` | Governance refused                                 |\n| `blocked` (`quarantine`)       |  `423` | Locked, released by a human                        |\n| `blocked` (`require_approval`) |  `428` | Precondition Required, approval queue              |\n| `internal_error` (anything)    |  `503` | Fail-closed; signer must refuse                    |\n\n## Authorization-token claims\n\n```ts\ninterface AuthorizationTokenClaims {\n  jti: string;                // recorded against the decision record\n  iss: string;                // your issuer URL\n  sub: string;                // org_id\n  aud: string;                // facilitator_url\n  iat: number;                // Unix seconds\n  exp: number;                // Unix seconds (default iat+120)\n  event_id: string;           // decision event id\n  ovt_fingerprint: string;    // audit replay key\n  rail: \"x402\";\n  rail_action: \"pay\";\n  pay_to_address: string;\n  amount_minor_units: string; // serialized bigint\n  asset: string;\n  chain: string;\n  reason_code: string;\n}\n```\n\nThe host signer JWS-signs these claims. The middleware itself never touches key material.\n\n## MPP charge intents\n\nThe package also maps Merchant Payment Protocol charge intents onto the same transfer shape, so one policy set covers both x402 and MPP without a second rule language. See `mpp-charge-intent.ts` and its tests for the mapping.\n\n## Related packages\n\n- [`@axiru/spec`](https://www.npmjs.com/package/@axiru/spec) is the policy and evidence vocabulary.\n- [`@axiru/x402-receipt-verifier`](https://www.npmjs.com/package/@axiru/x402-receipt-verifier) verifies the signed offers and receipts that come back after settlement.\n- [`@axiru/agent-spend-guardrails`](https://www.npmjs.com/package/@axiru/agent-spend-guardrails) is an in-process policy evaluator you can point `callDecisionEngine` at when you do not want a network hop.\n\n## License\n\nApache-2.0. Copyright 2026 Axiru. See [LICENSE](./LICENSE).\n","readmeFilename":"README.md"}