@arnaudjnn/billing-tools 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +243 -0
  3. package/dist/adapters/workos-org.d.ts +80 -0
  4. package/dist/adapters/workos-org.d.ts.map +1 -0
  5. package/dist/adapters/workos-org.js +176 -0
  6. package/dist/adapters/workos-org.js.map +1 -0
  7. package/dist/agent-auth/claim-store.d.ts +37 -0
  8. package/dist/agent-auth/claim-store.d.ts.map +1 -0
  9. package/dist/agent-auth/claim-store.js +64 -0
  10. package/dist/agent-auth/claim-store.js.map +1 -0
  11. package/dist/agent-auth/index.d.ts +65 -0
  12. package/dist/agent-auth/index.d.ts.map +1 -0
  13. package/dist/agent-auth/index.js +365 -0
  14. package/dist/agent-auth/index.js.map +1 -0
  15. package/dist/auth.d.ts +16 -0
  16. package/dist/auth.d.ts.map +1 -0
  17. package/dist/auth.js +80 -0
  18. package/dist/auth.js.map +1 -0
  19. package/dist/billing.d.ts +59 -0
  20. package/dist/billing.d.ts.map +1 -0
  21. package/dist/billing.js +258 -0
  22. package/dist/billing.js.map +1 -0
  23. package/dist/cli/client.d.ts +10 -0
  24. package/dist/cli/client.d.ts.map +1 -0
  25. package/dist/cli/client.js +22 -0
  26. package/dist/cli/client.js.map +1 -0
  27. package/dist/cli/commands.d.ts +4 -0
  28. package/dist/cli/commands.d.ts.map +1 -0
  29. package/dist/cli/commands.js +94 -0
  30. package/dist/cli/commands.js.map +1 -0
  31. package/dist/cli/config.d.ts +16 -0
  32. package/dist/cli/config.d.ts.map +1 -0
  33. package/dist/cli/config.js +40 -0
  34. package/dist/cli/config.js.map +1 -0
  35. package/dist/create-billing.d.ts +78 -0
  36. package/dist/create-billing.d.ts.map +1 -0
  37. package/dist/create-billing.js +59 -0
  38. package/dist/create-billing.js.map +1 -0
  39. package/dist/dispatch.d.ts +9 -0
  40. package/dist/dispatch.d.ts.map +1 -0
  41. package/dist/dispatch.js +73 -0
  42. package/dist/dispatch.js.map +1 -0
  43. package/dist/events.d.ts +26 -0
  44. package/dist/events.d.ts.map +1 -0
  45. package/dist/events.js +72 -0
  46. package/dist/events.js.map +1 -0
  47. package/dist/index.d.ts +24 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +40 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/invitations.d.ts +56 -0
  52. package/dist/invitations.d.ts.map +1 -0
  53. package/dist/invitations.js +117 -0
  54. package/dist/invitations.js.map +1 -0
  55. package/dist/machine-payment/index.d.ts +57 -0
  56. package/dist/machine-payment/index.d.ts.map +1 -0
  57. package/dist/machine-payment/index.js +117 -0
  58. package/dist/machine-payment/index.js.map +1 -0
  59. package/dist/magic-auth.d.ts +4 -0
  60. package/dist/magic-auth.d.ts.map +1 -0
  61. package/dist/magic-auth.js +30 -0
  62. package/dist/magic-auth.js.map +1 -0
  63. package/dist/mirror.d.ts +35 -0
  64. package/dist/mirror.d.ts.map +1 -0
  65. package/dist/mirror.js +63 -0
  66. package/dist/mirror.js.map +1 -0
  67. package/dist/plans.d.ts +38 -0
  68. package/dist/plans.d.ts.map +1 -0
  69. package/dist/plans.js +132 -0
  70. package/dist/plans.js.map +1 -0
  71. package/dist/routes/mcp.d.ts +19 -0
  72. package/dist/routes/mcp.d.ts.map +1 -0
  73. package/dist/routes/mcp.js +39 -0
  74. package/dist/routes/mcp.js.map +1 -0
  75. package/dist/routes/rest.d.ts +20 -0
  76. package/dist/routes/rest.d.ts.map +1 -0
  77. package/dist/routes/rest.js +66 -0
  78. package/dist/routes/rest.js.map +1 -0
  79. package/dist/routes/webhook.d.ts +8 -0
  80. package/dist/routes/webhook.d.ts.map +1 -0
  81. package/dist/routes/webhook.js +39 -0
  82. package/dist/routes/webhook.js.map +1 -0
  83. package/dist/sync.d.ts +58 -0
  84. package/dist/sync.d.ts.map +1 -0
  85. package/dist/sync.js +202 -0
  86. package/dist/sync.js.map +1 -0
  87. package/dist/tools/billing.d.ts +4 -0
  88. package/dist/tools/billing.d.ts.map +1 -0
  89. package/dist/tools/billing.js +125 -0
  90. package/dist/tools/billing.js.map +1 -0
  91. package/dist/tools/keys.d.ts +4 -0
  92. package/dist/tools/keys.d.ts.map +1 -0
  93. package/dist/tools/keys.js +107 -0
  94. package/dist/tools/keys.js.map +1 -0
  95. package/dist/tools/register.d.ts +20 -0
  96. package/dist/tools/register.d.ts.map +1 -0
  97. package/dist/tools/register.js +87 -0
  98. package/dist/tools/register.js.map +1 -0
  99. package/dist/types.d.ts +90 -0
  100. package/dist/types.d.ts.map +1 -0
  101. package/dist/types.js +28 -0
  102. package/dist/types.js.map +1 -0
  103. package/dist/util/clearout.d.ts +5 -0
  104. package/dist/util/clearout.d.ts.map +1 -0
  105. package/dist/util/clearout.js +18 -0
  106. package/dist/util/clearout.js.map +1 -0
  107. package/dist/workos.d.ts +6 -0
  108. package/dist/workos.d.ts.map +1 -0
  109. package/dist/workos.js +24 -0
  110. package/dist/workos.js.map +1 -0
  111. package/package.json +81 -0
@@ -0,0 +1,65 @@
1
+ import type { BillingAdapter, ResolvedConfig } from "../types.js";
2
+ import { type ClaimStore } from "./claim-store.js";
3
+ export declare const CLAIM_GRANT_TYPE = "urn:workos:agent-auth:grant-type:claim";
4
+ export type AgentIdentityType = "anonymous" | "verified_email";
5
+ export interface AgentAuthBranding {
6
+ /** Human-facing resource name (RFC 9728 resource_name, auth.md title). */
7
+ productName: string;
8
+ /** Absolute logo URL (RFC 9728 resource_logo_uri). Optional. */
9
+ logoUri?: string;
10
+ }
11
+ export interface AgentAuthPaths {
12
+ mcp?: string;
13
+ rest?: string;
14
+ authMd?: string;
15
+ protectedResource?: string;
16
+ authServer?: string;
17
+ identity?: string;
18
+ claim?: string;
19
+ token?: string;
20
+ revoke?: string;
21
+ }
22
+ export interface AgentAuthPolicy {
23
+ accessTokenTtl?: number;
24
+ interval?: number;
25
+ userCodeLength?: number;
26
+ scopes?: string[];
27
+ /** Domain for the synthetic anonymous email (anonymous+<stub>@<domain>). */
28
+ anonymousEmailDomain?: string;
29
+ /** Extra grant types to advertise in AS metadata (e.g. an app's MCP OAuth
30
+ * proxy adds "authorization_code"/"refresh_token"). */
31
+ extraGrantTypes?: string[];
32
+ }
33
+ export interface AgentAuthOptions {
34
+ adapter: BillingAdapter;
35
+ config: ResolvedConfig;
36
+ branding: AgentAuthBranding;
37
+ paths?: AgentAuthPaths;
38
+ /** Which identity types are enabled + advertised. Default both. "anonymous"
39
+ * additionally requires adapter.createAnonymousOrg. */
40
+ identityTypes?: AgentIdentityType[];
41
+ /** Base URL for absolute links. String, per-request resolver, or omitted to
42
+ * derive from the request's forwarded host/proto headers. */
43
+ baseUrl?: string | ((request: Request) => string);
44
+ claimStore?: ClaimStore;
45
+ policy?: AgentAuthPolicy;
46
+ /** Extra fields merged into the AS-metadata response (spread last, so they
47
+ * override defaults). Use for capabilities layered on top of auth.md — e.g.
48
+ * an MCP OAuth proxy's `authorization_endpoint` / `registration_endpoint`. */
49
+ asMetadataExtra?: Record<string, unknown>;
50
+ }
51
+ export declare function createAgentAuth(opts: AgentAuthOptions): {
52
+ protectedResource: (request: Request) => Response;
53
+ authorizationServer: (request: Request) => Response;
54
+ authMd: (request: Request) => Response;
55
+ identity: (request: Request) => Promise<Response>;
56
+ claim: (request: Request) => Promise<Response>;
57
+ token: (request: Request) => Promise<Response>;
58
+ handleClaimGrant: (params: Record<string, string>) => Promise<Response>;
59
+ revoke: (request: Request) => Promise<Response>;
60
+ /** Bare PRM discovery URL — pass as the REST/MCP factory `resourceMetadata`. */
61
+ resourceMetadataUrl: (request: Request) => string;
62
+ /** Full `WWW-Authenticate` value advertising the PRM discovery doc on a 401. */
63
+ wwwAuthenticate: (request: Request) => string;
64
+ };
65
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agent-auth/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlE,OAAO,EAAsB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAavE,eAAO,MAAM,gBAAgB,2CAA2C,CAAC;AAEzE,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,gBAAgB,CAAC;AAE/D,MAAM,WAAW,iBAAiB;IAChC,0EAA0E;IAC1E,WAAW,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,4EAA4E;IAC5E,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;4DACwD;IACxD,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE,cAAc,CAAC;IACvB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB;4DACwD;IACxD,aAAa,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACpC;kEAC8D;IAC9D,OAAO,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,CAAC,CAAC;IAClD,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB;;mFAE+E;IAC/E,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC3C;AAiCD,wBAAgB,eAAe,CAAC,IAAI,EAAE,gBAAgB;iCA2BhB,OAAO,KAAG,QAAQ;mCAehB,OAAO,KAAG,QAAQ;sBAiC/B,OAAO,KAAG,QAAQ;wBAgDV,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAC;qBA8B9B,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAC;qBAsD3B,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAC;+BAvBjB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAG,OAAO,CAAC,QAAQ,CAAC;sBAkCnD,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAC;IAuBxD,gFAAgF;mCACjD,OAAO;IACtC,gFAAgF;+BACrD,OAAO;EAGrC"}
@@ -0,0 +1,365 @@
1
+ import { sendMagicAuth, verifyMagicAuth } from "../magic-auth.js";
2
+ import { ensureStripeCustomer } from "../billing.js";
3
+ import { inMemoryClaimStore } from "./claim-store.js";
4
+ // auth.md — the WorkOS agent-registration protocol (https://workos.com/auth-md),
5
+ // as reusable framework-agnostic handlers. An autonomous agent can self-register
6
+ // and obtain an API key with no human signup. Everything flows through the
7
+ // BillingAdapter + magic-auth (no direct WorkOS calls here), so any Stripe+WorkOS
8
+ // app mounts these by re-exporting them from its route files.
9
+ //
10
+ // Identity types (advertised + enabled via `identityTypes`):
11
+ // - "anonymous": mint a fresh org + key immediately (needs adapter.createAnonymousOrg).
12
+ // - "verified_email": email OTP ceremony → key bound to the user's workspace.
13
+ // ID-JAG is deferred (returns issuer_not_enabled) until agent providers ship it.
14
+ export const CLAIM_GRANT_TYPE = "urn:workos:agent-auth:grant-type:claim";
15
+ const YEAR = 365 * 24 * 60 * 60;
16
+ function jsonError(error, description, status = 400) {
17
+ return Response.json({ error, error_description: description }, { status });
18
+ }
19
+ function baseUrlFromRequest(request) {
20
+ const h = request.headers;
21
+ const host = h.get("x-forwarded-host") ?? h.get("host");
22
+ const proto = h.get("x-forwarded-proto") ?? (host?.startsWith("localhost") ? "http" : "https");
23
+ if (host)
24
+ return `${proto}://${host}`;
25
+ return new URL(request.url).origin;
26
+ }
27
+ async function readBody(request) {
28
+ const ct = request.headers.get("content-type") ?? "";
29
+ try {
30
+ if (ct.includes("application/x-www-form-urlencoded")) {
31
+ const form = await request.formData();
32
+ const out = {};
33
+ form.forEach((v, k) => {
34
+ out[k] = String(v);
35
+ });
36
+ return out;
37
+ }
38
+ return (await request.json());
39
+ }
40
+ catch {
41
+ return null;
42
+ }
43
+ }
44
+ export function createAgentAuth(opts) {
45
+ const { adapter, config, branding } = opts;
46
+ const store = opts.claimStore ?? inMemoryClaimStore();
47
+ const types = new Set(opts.identityTypes ?? ["anonymous", "verified_email"]);
48
+ const p = {
49
+ mcp: "/mcp",
50
+ rest: "/api/v0",
51
+ authMd: "/auth.md",
52
+ protectedResource: "/.well-known/oauth-protected-resource",
53
+ authServer: "/.well-known/oauth-authorization-server",
54
+ identity: "/agent/identity",
55
+ claim: "/agent/identity/claim",
56
+ token: "/oauth/token",
57
+ revoke: "/oauth/revoke",
58
+ ...opts.paths,
59
+ };
60
+ const policy = opts.policy ?? {};
61
+ const ttl = policy.accessTokenTtl ?? YEAR;
62
+ const scopes = policy.scopes ?? ["openid", "profile", "email"];
63
+ const baseUrlOf = (request) => typeof opts.baseUrl === "function"
64
+ ? opts.baseUrl(request)
65
+ : (opts.baseUrl ?? baseUrlFromRequest(request));
66
+ // ── Discovery ────────────────────────────────────────────────────────────
67
+ function protectedResource(request) {
68
+ const b = baseUrlOf(request);
69
+ return Response.json({
70
+ resource: `${b}${p.mcp}`,
71
+ resource_name: branding.productName,
72
+ ...(branding.logoUri ? { resource_logo_uri: branding.logoUri } : {}),
73
+ authorization_servers: [b],
74
+ scopes_supported: scopes,
75
+ bearer_methods_supported: ["header"],
76
+ }, { headers: { "Cache-Control": "public, max-age=3600" } });
77
+ }
78
+ function authorizationServer(request) {
79
+ const b = baseUrlOf(request);
80
+ const assertionTypes = types.has("verified_email") ? ["verified_email"] : [];
81
+ const identityTypesSupported = [
82
+ ...(types.has("anonymous") ? ["anonymous"] : []),
83
+ ...(types.has("verified_email") ? ["identity_assertion"] : []),
84
+ ];
85
+ return Response.json({
86
+ issuer: b,
87
+ authorization_endpoint: `${b}/oauth/authorize`,
88
+ token_endpoint: `${b}${p.token}`,
89
+ revocation_endpoint: `${b}${p.revoke}`,
90
+ response_types_supported: ["code"],
91
+ grant_types_supported: [...(policy.extraGrantTypes ?? []), CLAIM_GRANT_TYPE],
92
+ token_endpoint_auth_methods_supported: ["none"],
93
+ code_challenge_methods_supported: ["S256", "plain"],
94
+ scopes_supported: scopes,
95
+ agent_auth: {
96
+ skill: `${b}${p.authMd}`,
97
+ identity_endpoint: `${b}${p.identity}`,
98
+ claim_endpoint: `${b}${p.claim}`,
99
+ identity_types_supported: identityTypesSupported,
100
+ ...(assertionTypes.length
101
+ ? { identity_assertion: { assertion_types_supported: assertionTypes } }
102
+ : {}),
103
+ },
104
+ ...(opts.asMetadataExtra ?? {}),
105
+ }, { headers: { "Cache-Control": "public, max-age=3600" } });
106
+ }
107
+ function authMd(request) {
108
+ return new Response(renderAuthMd(baseUrlOf(request), branding.productName, p, types, ttl), {
109
+ headers: {
110
+ "content-type": "text/markdown; charset=utf-8",
111
+ "cache-control": "public, max-age=3600",
112
+ },
113
+ });
114
+ }
115
+ // ── Registration ──────────────────────────────────────────────────────────
116
+ async function handleAnonymous() {
117
+ if (!types.has("anonymous") || !adapter.createAnonymousOrg) {
118
+ return jsonError("anonymous_not_enabled", "Anonymous registration is not enabled", 400);
119
+ }
120
+ const stub = `anon-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
121
+ const { orgId } = await adapter.createAnonymousOrg({
122
+ name: `Anonymous agent (${stub})`,
123
+ metadata: { authMd: "anonymous" },
124
+ });
125
+ const domain = policy.anonymousEmailDomain ?? "example.invalid";
126
+ await ensureStripeCustomer(adapter, orgId, `anonymous+${stub}@${domain}`, config);
127
+ const key = await adapter.mintApiKey(orgId, `auth.md anonymous (${today()})`);
128
+ return Response.json({
129
+ access_token: key.value,
130
+ token_type: "bearer",
131
+ expires_in: ttl,
132
+ scope: "api",
133
+ organization_id: orgId,
134
+ });
135
+ }
136
+ async function handleVerifiedEmail(email) {
137
+ try {
138
+ await sendMagicAuth(email);
139
+ }
140
+ catch (e) {
141
+ return jsonError("server_error", `Failed to send verification code: ${msg(e)}`, 500);
142
+ }
143
+ const { claimToken, expiresIn } = await store.create(email);
144
+ return Response.json({
145
+ claim_token: claimToken,
146
+ expires_in: expiresIn,
147
+ interval: policy.interval ?? 2,
148
+ verification_uri: `${p.claim}`,
149
+ user_code_length: policy.userCodeLength ?? 6,
150
+ });
151
+ }
152
+ async function identity(request) {
153
+ const body = await readBody(request);
154
+ if (!body)
155
+ return jsonError("invalid_request", "Body must be JSON");
156
+ const type = body.type;
157
+ if (type === "anonymous") {
158
+ try {
159
+ return await handleAnonymous();
160
+ }
161
+ catch (e) {
162
+ return jsonError("server_error", msg(e), 500);
163
+ }
164
+ }
165
+ if (type === "identity_assertion") {
166
+ const at = body.assertion_type;
167
+ const assertion = body.assertion;
168
+ if (typeof at !== "string")
169
+ return jsonError("invalid_request", "assertion_type is required");
170
+ if (at === "urn:ietf:params:oauth:token-type:id-jag") {
171
+ return jsonError("issuer_not_enabled", "ID-JAG assertions are not yet accepted");
172
+ }
173
+ if (at !== "verified_email" || !types.has("verified_email")) {
174
+ return jsonError("invalid_request", `Unsupported assertion_type: ${at}`);
175
+ }
176
+ if (typeof assertion !== "string" || !assertion.includes("@")) {
177
+ return jsonError("invalid_request", "assertion must be a valid email for verified_email");
178
+ }
179
+ return handleVerifiedEmail(assertion);
180
+ }
181
+ return jsonError("invalid_request", "type must be one of: anonymous, identity_assertion");
182
+ }
183
+ async function claim(request) {
184
+ const body = await readBody(request);
185
+ if (!body)
186
+ return jsonError("invalid_request", "Body must be JSON");
187
+ const claimToken = body.claim_token;
188
+ const userCode = body.user_code;
189
+ if (typeof claimToken !== "string" || typeof userCode !== "string") {
190
+ return jsonError("invalid_request", "claim_token and user_code are required");
191
+ }
192
+ const entry = await store.get(claimToken);
193
+ if (entry.status === "not_found")
194
+ return jsonError("invalid_claim_token", "Unknown or expired claim_token");
195
+ if (entry.status === "ready")
196
+ return Response.json({ status: "ready" });
197
+ if (entry.status === "error")
198
+ return jsonError("invalid_grant", entry.error);
199
+ try {
200
+ const user = await verifyMagicAuth(entry.email, userCode);
201
+ const { orgId } = await adapter.ensureOrgForUser(user);
202
+ await ensureStripeCustomer(adapter, orgId, entry.email, config);
203
+ const key = await adapter.mintApiKey(orgId, `auth.md (${today()})`);
204
+ await store.markReady(claimToken, { apiKey: key.value, organizationId: orgId });
205
+ return Response.json({ status: "ready" });
206
+ }
207
+ catch (e) {
208
+ await store.markError(claimToken, msg(e));
209
+ return jsonError("invalid_grant", msg(e));
210
+ }
211
+ }
212
+ // ── Token (claim polling grant) ─────────────────────────────────────────────
213
+ /** Handle the claim polling grant. Call from an app's existing /oauth/token
214
+ * route when grant_type === CLAIM_GRANT_TYPE, or use the `token` handler. */
215
+ async function handleClaimGrant(params) {
216
+ const claimToken = params.claim_token;
217
+ if (!claimToken)
218
+ return jsonError("invalid_request", "claim_token is required");
219
+ const peek = await store.get(claimToken);
220
+ if (peek.status === "not_found")
221
+ return jsonError("invalid_grant", "Unknown or expired claim_token");
222
+ if (peek.status === "pending") {
223
+ return jsonError("authorization_pending", "Waiting for the user to confirm the code");
224
+ }
225
+ const consumed = await store.consume(claimToken);
226
+ if (consumed.status === "ready") {
227
+ return Response.json({
228
+ access_token: consumed.apiKey,
229
+ token_type: "bearer",
230
+ expires_in: ttl,
231
+ scope: "api",
232
+ organization_id: consumed.organizationId,
233
+ });
234
+ }
235
+ if (consumed.status === "error")
236
+ return jsonError("invalid_grant", consumed.error);
237
+ return jsonError("authorization_pending", "Retry");
238
+ }
239
+ async function token(request) {
240
+ const params = await readBody(request);
241
+ if (!params)
242
+ return jsonError("invalid_request", "Invalid request body");
243
+ if (params.grant_type !== CLAIM_GRANT_TYPE) {
244
+ return jsonError("unsupported_grant_type", `Supported grant type: ${CLAIM_GRANT_TYPE}`);
245
+ }
246
+ return handleClaimGrant(params);
247
+ }
248
+ // ── Revocation (RFC 7009) ────────────────────────────────────────────────
249
+ async function revoke(request) {
250
+ const params = await readBody(request);
251
+ const t = params?.token;
252
+ // Per RFC 7009, always 200 (never leak token existence). Best-effort revoke.
253
+ if (t && adapter.revokeApiKeyByToken) {
254
+ try {
255
+ await adapter.revokeApiKeyByToken(t);
256
+ }
257
+ catch {
258
+ /* swallow — spec mandates 200 regardless */
259
+ }
260
+ }
261
+ return new Response(null, { status: 200 });
262
+ }
263
+ return {
264
+ protectedResource,
265
+ authorizationServer,
266
+ authMd,
267
+ identity,
268
+ claim,
269
+ token,
270
+ handleClaimGrant,
271
+ revoke,
272
+ /** Bare PRM discovery URL — pass as the REST/MCP factory `resourceMetadata`. */
273
+ resourceMetadataUrl: (request) => `${baseUrlOf(request)}${p.protectedResource}`,
274
+ /** Full `WWW-Authenticate` value advertising the PRM discovery doc on a 401. */
275
+ wwwAuthenticate: (request) => `Bearer resource_metadata="${baseUrlOf(request)}${p.protectedResource}"`,
276
+ };
277
+ }
278
+ function today() {
279
+ // Callers pass a name only for display; avoid Date in a way that's fine here.
280
+ return new Date().toISOString().slice(0, 10);
281
+ }
282
+ function msg(e) {
283
+ return e instanceof Error ? e.message : String(e);
284
+ }
285
+ function renderAuthMd(baseUrl, product, p, types, ttl) {
286
+ const rows = [];
287
+ if (types.has("anonymous")) {
288
+ rows.push(`| \`anonymous\` | — | You have no user context. You get a working API key immediately. |`);
289
+ }
290
+ if (types.has("verified_email")) {
291
+ rows.push(`| \`identity_assertion\` | \`verified_email\` | You know the user's email. They confirm a 6-digit code; you get a key bound to their workspace. |`);
292
+ }
293
+ return `# ${product} — auth.md
294
+
295
+ This service implements the [auth.md](https://workos.com/auth-md) agent-registration protocol.
296
+ You (an autonomous agent) can register and obtain an API key without a human filling out a form.
297
+
298
+ ## Step 1 — Discover
299
+
300
+ \`\`\`http
301
+ GET ${baseUrl}${p.authServer}
302
+ \`\`\`
303
+
304
+ The response includes an \`agent_auth\` block with the endpoints below.
305
+
306
+ ## Step 2 — Pick a method
307
+
308
+ | \`type\` | \`assertion_type\` | When to use |
309
+ |---|---|---|
310
+ ${rows.join("\n")}
311
+
312
+ ## Step 3 — Register
313
+
314
+ \`\`\`http
315
+ POST ${baseUrl}${p.identity}
316
+ Content-Type: application/json
317
+ \`\`\`
318
+ ${types.has("anonymous")
319
+ ? `
320
+ **Anonymous:** \`{ "type": "anonymous" }\` → \`{ "access_token": "sk_…", "token_type": "bearer", "expires_in": ${ttl}, "scope": "api" }\`. Use the key directly in \`Authorization: Bearer …\` against \`${baseUrl}${p.mcp}\` or \`${baseUrl}${p.rest}/{tool_name}\`.
321
+ `
322
+ : ""}${types.has("verified_email")
323
+ ? `
324
+ **Verified email:** \`{ "type": "identity_assertion", "assertion_type": "verified_email", "assertion": "user@example.com" }\` → the service emails the user a 6-digit code and returns \`{ "claim_token": "clm_…", "interval": 2, "user_code_length": 6 }\`. Continue to Step 4.
325
+
326
+ ## Step 4 — Claim ceremony
327
+
328
+ The user reads back the code; submit it:
329
+
330
+ \`\`\`http
331
+ POST ${baseUrl}${p.claim}
332
+ Content-Type: application/json
333
+
334
+ { "claim_token": "clm_…", "user_code": "123456" }
335
+ \`\`\`
336
+
337
+ ## Step 5 — Exchange the claim for an access token
338
+
339
+ \`\`\`http
340
+ POST ${baseUrl}${p.token}
341
+ Content-Type: application/x-www-form-urlencoded
342
+
343
+ grant_type=${CLAIM_GRANT_TYPE}&claim_token=clm_…
344
+ \`\`\`
345
+
346
+ Returns \`{ "error": "authorization_pending" }\` until the code is entered, then \`{ "access_token": "sk_…", "token_type": "bearer", "expires_in": ${ttl}, "scope": "api" }\`.
347
+ `
348
+ : ""}
349
+ ## Use the access token
350
+
351
+ All MCP (\`${baseUrl}${p.mcp}\`) and REST (\`${baseUrl}${p.rest}/{tool_name}\`) endpoints accept the same key. Free tools work immediately; paid tools require a token balance.
352
+
353
+ ## Revocation
354
+
355
+ \`\`\`http
356
+ POST ${baseUrl}${p.revoke}
357
+ Content-Type: application/x-www-form-urlencoded
358
+
359
+ token=sk_…&token_type_hint=access_token
360
+ \`\`\`
361
+
362
+ Returns 200 (per RFC 7009; same response whether or not the token existed).
363
+ `;
364
+ }
365
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/agent-auth/index.ts"],"names":[],"mappings":"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"}
package/dist/auth.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ import type { BillingAdapter, ResolvedConfig, ToolErrorResult } from "./types.js";
3
+ interface AuthStore {
4
+ authHeader: string | null;
5
+ orgId?: string;
6
+ }
7
+ export declare const authContext: AsyncLocalStorage<AuthStore>;
8
+ export declare function runWithAuth<T>(header: string | null, fn: () => T): T;
9
+ export declare function runWithResolvedOrg<T>(header: string | null, orgId: string, fn: () => T): T;
10
+ export declare function enforceAccess(adapter: BillingAdapter): Promise<{
11
+ authorized: true;
12
+ orgId: string;
13
+ } | ToolErrorResult>;
14
+ export declare function enforceTokens(adapter: BillingAdapter, config: ResolvedConfig, orgId: string, toolName: string, cost: number): Promise<ToolErrorResult | null>;
15
+ export {};
16
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AASlF,UAAU,SAAS;IACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAG1B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,WAAW,8BAAqC,CAAC;AAE9D,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAEpE;AAGD,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAE1F;AAKD,wBAAsB,aAAa,CACjC,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC;IAAE,UAAU,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,eAAe,CAAC,CAyBhE;AAgBD,wBAAsB,aAAa,CACjC,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,cAAc,EACtB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CA2BjC"}
package/dist/auth.js ADDED
@@ -0,0 +1,80 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ import { getBillingCustomerId, getTokenBalance, deductTokens, tryAutoReload, stripeConfigured, } from "./billing.js";
3
+ export const authContext = new AsyncLocalStorage();
4
+ export function runWithAuth(header, fn) {
5
+ return authContext.run({ authHeader: header }, fn);
6
+ }
7
+ // Used by the MCP transport's OAuth path: run with a pre-resolved org.
8
+ export function runWithResolvedOrg(header, orgId, fn) {
9
+ return authContext.run({ authHeader: header, orgId }, fn);
10
+ }
11
+ // Resolve the caller's org from the Bearer API key (via the adapter). Returns
12
+ // the org id or a parseable 401 envelope (REST/MCP layers sniff "Unauthorized
13
+ // (401)" to map to HTTP 401 + WWW-Authenticate).
14
+ export async function enforceAccess(adapter) {
15
+ const store = authContext.getStore();
16
+ if (store?.orgId)
17
+ return { authorized: true, orgId: store.orgId };
18
+ const header = store?.authHeader;
19
+ if (!header || !header.startsWith("Bearer ")) {
20
+ return {
21
+ isError: true,
22
+ content: [
23
+ {
24
+ type: "text",
25
+ text: "Unauthorized (401): Missing or malformed Authorization header. Use get_api_key to obtain an API key.",
26
+ },
27
+ ],
28
+ };
29
+ }
30
+ const token = header.slice("Bearer ".length).trim();
31
+ const resolved = await adapter.validateApiKey(token);
32
+ if (!resolved) {
33
+ return {
34
+ isError: true,
35
+ content: [{ type: "text", text: "Unauthorized (401): Invalid API key." }],
36
+ };
37
+ }
38
+ return { authorized: true, orgId: resolved.orgId };
39
+ }
40
+ async function isInternalOrg(adapter, orgId, internalDomains) {
41
+ if (internalDomains.length === 0)
42
+ return false;
43
+ const set = new Set(internalDomains.map((d) => d.toLowerCase()));
44
+ const domains = await adapter.getOrgDomains(orgId);
45
+ return domains.some((d) => set.has(d.toLowerCase()));
46
+ }
47
+ // Metering gate for paid tools. Free (cost 0), Stripe-unset, and internal orgs
48
+ // are skipped. Otherwise deduct from the org's token balance and fire
49
+ // auto-reload in the background.
50
+ export async function enforceTokens(adapter, config, orgId, toolName, cost) {
51
+ if (!cost)
52
+ return null;
53
+ if (!stripeConfigured())
54
+ return null;
55
+ if (await isInternalOrg(adapter, orgId, config.internalDomains))
56
+ return null;
57
+ const customerId = await getBillingCustomerId(adapter, orgId);
58
+ if (!customerId) {
59
+ return {
60
+ isError: true,
61
+ content: [{ type: "text", text: "No billing account found. Please contact support." }],
62
+ };
63
+ }
64
+ const balance = await getTokenBalance(customerId);
65
+ if (balance < cost) {
66
+ return {
67
+ isError: true,
68
+ content: [
69
+ {
70
+ type: "text",
71
+ text: `Insufficient tokens. This tool costs ${cost} tokens but you only have ${balance}. Use buy_tokens to purchase more.`,
72
+ },
73
+ ],
74
+ };
75
+ }
76
+ await deductTokens(customerId, toolName, cost, config.currency);
77
+ tryAutoReload(customerId, config.currency).catch(() => { });
78
+ return null;
79
+ }
80
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ import Stripe from "stripe";
2
+ import type { BillingAdapter, ResolvedConfig } from "./types.js";
3
+ export declare function getStripe(): Stripe;
4
+ export declare function stripeConfigured(): boolean;
5
+ export interface StripePrice {
6
+ id: string;
7
+ productId: string | null;
8
+ productName: string | null;
9
+ lookupKey: string | null;
10
+ nickname: string | null;
11
+ unitAmount: number | null;
12
+ currency: string;
13
+ interval: string | null;
14
+ intervalCount: number | null;
15
+ }
16
+ /** All active recurring (subscription) prices on the Stripe account. Uses the
17
+ * SDK's async auto-pagination so accounts with >1 page of prices aren't
18
+ * silently truncated. */
19
+ export declare function listSubscriptionPrices(): Promise<StripePrice[]>;
20
+ /** Resolve a single subscription price without any env config. Resolution
21
+ * order: explicit `priceId` → matching `lookupKey` → the sole recurring price.
22
+ * Returns null if nothing matches or the choice is ambiguous (multiple prices,
23
+ * no lookupKey) — the caller can then list options via listSubscriptionPrices.
24
+ * The priceId/lookupKey paths query Stripe directly (no full-list scan). */
25
+ export declare function resolveSubscriptionPrice(opts?: {
26
+ priceId?: string;
27
+ lookupKey?: string;
28
+ }): Promise<StripePrice | null>;
29
+ export declare function getBillingCustomerId(adapter: BillingAdapter, orgId: string): Promise<string | null>;
30
+ export declare function ensureStripeCustomer(adapter: BillingAdapter, orgId: string, email: string | undefined, config: ResolvedConfig): Promise<string>;
31
+ export declare function getTokenBalance(stripeCustomerId: string): Promise<number>;
32
+ export declare function deductTokens(stripeCustomerId: string, toolName: string, cost: number, currency: string): Promise<void>;
33
+ export declare function creditTokens(stripeCustomerId: string, amount: number, description: string, currency: string,
34
+ /** Pass a stable key (e.g. the source invoice/session id) so replayed events
35
+ * — a re-delivered webhook, an overlapping poll — credit exactly once. */
36
+ idempotencyKey?: string): Promise<void>;
37
+ export declare function createTokenCheckoutSession(stripeCustomerId: string, orgId: string, amountMajor: number, config: ResolvedConfig): Promise<string>;
38
+ /** A Stripe Billing Portal session URL — the no-code self-serve surface where a
39
+ * customer manages their subscription (upgrade/downgrade/cancel), updates the
40
+ * payment method (fixes a failing card), and views invoices. */
41
+ export declare function createBillingPortalSession(stripeCustomerId: string, returnUrl: string): Promise<string>;
42
+ export declare function getAutoReloadSettings(stripeCustomerId: string): Promise<{
43
+ enabled: boolean;
44
+ threshold: number;
45
+ reload_to: number;
46
+ } | null>;
47
+ export declare function setAutoReloadSettings(stripeCustomerId: string, threshold: number, reloadTo: number, enabled: boolean): Promise<void>;
48
+ export declare function tryAutoReload(stripeCustomerId: string, currency: string): Promise<void>;
49
+ export declare function listInvoices(stripeCustomerId: string, limit?: number): Promise<Array<{
50
+ id: string;
51
+ type: string;
52
+ number: string | null;
53
+ amount: number;
54
+ status: string | null;
55
+ created: string;
56
+ invoice_url: string | null;
57
+ invoice_pdf: string | null;
58
+ }>>;
59
+ //# sourceMappingURL=billing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"billing.d.ts","sourceRoot":"","sources":["../src/billing.ts"],"names":[],"mappings":"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"}