@every-app/sdk 0.2.0 → 0.3.0-rc.10

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 (189) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +609 -3
  3. package/dist/cloudflare/catalogSettings.generated.d.ts +81 -0
  4. package/dist/cloudflare/catalogSettings.generated.d.ts.map +1 -0
  5. package/dist/cloudflare/catalogSettings.generated.js +174 -0
  6. package/dist/cloudflare/index.d.ts +23 -0
  7. package/dist/cloudflare/index.d.ts.map +1 -0
  8. package/dist/cloudflare/index.js +24 -0
  9. package/dist/cloudflare/sentinel.d.ts +127 -0
  10. package/dist/cloudflare/sentinel.d.ts.map +1 -0
  11. package/dist/cloudflare/sentinel.js +85 -0
  12. package/dist/cloudflare/worker.d.ts +805 -0
  13. package/dist/cloudflare/worker.d.ts.map +1 -0
  14. package/dist/cloudflare/worker.js +997 -0
  15. package/dist/dev/index.d.ts +8 -0
  16. package/dist/dev/index.d.ts.map +1 -0
  17. package/dist/dev/index.js +7 -0
  18. package/dist/dev/keypair.d.ts +26 -0
  19. package/dist/dev/keypair.d.ts.map +1 -0
  20. package/dist/dev/keypair.js +62 -0
  21. package/dist/index.d.ts +6 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +5 -0
  24. package/dist/internal/aiDefault.d.ts +204 -0
  25. package/dist/internal/aiDefault.d.ts.map +1 -0
  26. package/dist/internal/aiDefault.js +334 -0
  27. package/dist/internal/aiProviders.d.ts +72 -0
  28. package/dist/internal/aiProviders.d.ts.map +1 -0
  29. package/dist/internal/aiProviders.js +233 -0
  30. package/dist/internal/appSettings.d.ts +315 -0
  31. package/dist/internal/appSettings.d.ts.map +1 -0
  32. package/dist/internal/appSettings.js +549 -0
  33. package/dist/internal/audit.d.ts +108 -0
  34. package/dist/internal/audit.d.ts.map +1 -0
  35. package/dist/internal/audit.js +235 -0
  36. package/dist/internal/capabilities.d.ts +3174 -0
  37. package/dist/internal/capabilities.d.ts.map +1 -0
  38. package/dist/internal/capabilities.js +1110 -0
  39. package/dist/internal/catalog/commerce.d.ts +394 -0
  40. package/dist/internal/catalog/commerce.d.ts.map +1 -0
  41. package/dist/internal/catalog/commerce.js +477 -0
  42. package/dist/internal/catalog/comms.d.ts +375 -0
  43. package/dist/internal/catalog/comms.d.ts.map +1 -0
  44. package/dist/internal/catalog/comms.js +520 -0
  45. package/dist/internal/catalog/index.d.ts +1973 -0
  46. package/dist/internal/catalog/index.d.ts.map +1 -0
  47. package/dist/internal/catalog/index.js +19 -0
  48. package/dist/internal/catalog/inference.d.ts +393 -0
  49. package/dist/internal/catalog/inference.d.ts.map +1 -0
  50. package/dist/internal/catalog/inference.js +460 -0
  51. package/dist/internal/catalog/infra.d.ts +423 -0
  52. package/dist/internal/catalog/infra.d.ts.map +1 -0
  53. package/dist/internal/catalog/infra.js +543 -0
  54. package/dist/internal/catalog/search.d.ts +400 -0
  55. package/dist/internal/catalog/search.d.ts.map +1 -0
  56. package/dist/internal/catalog/search.js +463 -0
  57. package/dist/internal/devProviders.d.ts +49 -0
  58. package/dist/internal/devProviders.d.ts.map +1 -0
  59. package/dist/internal/devProviders.js +80 -0
  60. package/dist/internal/email.d.ts +280 -0
  61. package/dist/internal/email.d.ts.map +1 -0
  62. package/dist/internal/email.js +613 -0
  63. package/dist/internal/events.d.ts +193 -0
  64. package/dist/internal/events.d.ts.map +1 -0
  65. package/dist/internal/events.js +367 -0
  66. package/dist/internal/gatewaySettings.d.ts +83 -0
  67. package/dist/internal/gatewaySettings.d.ts.map +1 -0
  68. package/dist/internal/gatewaySettings.js +215 -0
  69. package/dist/internal/identity.d.ts +57 -5
  70. package/dist/internal/identity.d.ts.map +1 -1
  71. package/dist/internal/identity.js +99 -22
  72. package/dist/internal/index.d.ts +22 -1
  73. package/dist/internal/index.d.ts.map +1 -1
  74. package/dist/internal/index.js +22 -1
  75. package/dist/internal/members.d.ts +36 -0
  76. package/dist/internal/members.d.ts.map +1 -0
  77. package/dist/internal/members.js +7 -0
  78. package/dist/internal/oauthClient.d.ts +61 -0
  79. package/dist/internal/oauthClient.d.ts.map +1 -0
  80. package/dist/internal/oauthClient.js +133 -0
  81. package/dist/internal/oauthPresets.d.ts +33 -0
  82. package/dist/internal/oauthPresets.d.ts.map +1 -0
  83. package/dist/internal/oauthPresets.js +1064 -0
  84. package/dist/internal/oauthScopes.d.ts +172 -0
  85. package/dist/internal/oauthScopes.d.ts.map +1 -0
  86. package/dist/internal/oauthScopes.js +510 -0
  87. package/dist/internal/oauthSpec.d.ts +102 -0
  88. package/dist/internal/oauthSpec.d.ts.map +1 -0
  89. package/dist/internal/oauthSpec.js +789 -0
  90. package/dist/internal/organizationName.d.ts +18 -0
  91. package/dist/internal/organizationName.d.ts.map +1 -0
  92. package/dist/internal/organizationName.js +24 -0
  93. package/dist/internal/protocol.d.ts +150 -3
  94. package/dist/internal/protocol.d.ts.map +1 -1
  95. package/dist/internal/protocol.js +163 -2
  96. package/dist/internal/providerApps.d.ts +75 -0
  97. package/dist/internal/providerApps.d.ts.map +1 -0
  98. package/dist/internal/providerApps.js +59 -0
  99. package/dist/internal/providerRegistry.d.ts +218 -0
  100. package/dist/internal/providerRegistry.d.ts.map +1 -0
  101. package/dist/internal/providerRegistry.js +432 -0
  102. package/dist/internal/providerSpec.d.ts +66 -0
  103. package/dist/internal/providerSpec.d.ts.map +1 -0
  104. package/dist/internal/providerSpec.js +1154 -0
  105. package/dist/internal/remoteMcp.d.ts +188 -0
  106. package/dist/internal/remoteMcp.d.ts.map +1 -0
  107. package/dist/internal/remoteMcp.js +543 -0
  108. package/dist/internal/signInProviders.d.ts +104 -0
  109. package/dist/internal/signInProviders.d.ts.map +1 -0
  110. package/dist/internal/signInProviders.js +245 -0
  111. package/dist/internal/tools.d.ts +115 -0
  112. package/dist/internal/tools.d.ts.map +1 -0
  113. package/dist/internal/tools.js +80 -0
  114. package/dist/manifest.d.ts +238 -0
  115. package/dist/manifest.d.ts.map +1 -0
  116. package/dist/manifest.js +30 -0
  117. package/dist/server/ai.d.ts +111 -0
  118. package/dist/server/ai.d.ts.map +1 -0
  119. package/dist/server/ai.js +145 -0
  120. package/dist/server/aiBinding.d.ts +68 -0
  121. package/dist/server/aiBinding.d.ts.map +1 -0
  122. package/dist/server/aiBinding.js +294 -0
  123. package/dist/server/attribution.d.ts +43 -0
  124. package/dist/server/attribution.d.ts.map +1 -0
  125. package/dist/server/attribution.js +75 -0
  126. package/dist/server/authorizeUrl.d.ts +43 -0
  127. package/dist/server/authorizeUrl.d.ts.map +1 -0
  128. package/dist/server/authorizeUrl.js +106 -0
  129. package/dist/server/connectUrl.d.ts +21 -0
  130. package/dist/server/connectUrl.d.ts.map +1 -0
  131. package/dist/server/connectUrl.js +37 -0
  132. package/dist/server/context.d.ts +68 -0
  133. package/dist/server/context.d.ts.map +1 -0
  134. package/dist/server/context.js +117 -0
  135. package/dist/server/emailBinding.d.ts +72 -0
  136. package/dist/server/emailBinding.d.ts.map +1 -0
  137. package/dist/server/emailBinding.js +124 -0
  138. package/dist/server/emit.d.ts +63 -0
  139. package/dist/server/emit.d.ts.map +1 -0
  140. package/dist/server/emit.js +101 -0
  141. package/dist/server/env.d.ts +44 -0
  142. package/dist/server/env.d.ts.map +1 -0
  143. package/dist/server/env.js +1 -0
  144. package/dist/server/everyApp.d.ts +65 -19
  145. package/dist/server/everyApp.d.ts.map +1 -1
  146. package/dist/server/everyApp.js +195 -30
  147. package/dist/server/fromMcpTools.d.ts +89 -0
  148. package/dist/server/fromMcpTools.d.ts.map +1 -0
  149. package/dist/server/fromMcpTools.js +192 -0
  150. package/dist/server/gatewayFetch.d.ts +54 -14
  151. package/dist/server/gatewayFetch.d.ts.map +1 -1
  152. package/dist/server/gatewayFetch.js +201 -37
  153. package/dist/server/gatewayUrl.d.ts +13 -0
  154. package/dist/server/gatewayUrl.d.ts.map +1 -0
  155. package/dist/server/gatewayUrl.js +34 -0
  156. package/dist/server/index.d.ts +23 -3
  157. package/dist/server/index.d.ts.map +1 -1
  158. package/dist/server/index.js +19 -2
  159. package/dist/server/integrationFetch.d.ts +162 -0
  160. package/dist/server/integrationFetch.d.ts.map +1 -0
  161. package/dist/server/integrationFetch.js +688 -0
  162. package/dist/server/listMembers.d.ts +32 -0
  163. package/dist/server/listMembers.d.ts.map +1 -0
  164. package/dist/server/listMembers.js +71 -0
  165. package/dist/server/nodeServer.d.ts +48 -0
  166. package/dist/server/nodeServer.d.ts.map +1 -0
  167. package/dist/server/nodeServer.js +45 -0
  168. package/dist/server/refusal.d.ts +55 -0
  169. package/dist/server/refusal.d.ts.map +1 -0
  170. package/dist/server/refusal.js +193 -0
  171. package/dist/server/sendEmail.d.ts +39 -0
  172. package/dist/server/sendEmail.d.ts.map +1 -0
  173. package/dist/server/sendEmail.js +114 -0
  174. package/dist/server/tools.d.ts +184 -0
  175. package/dist/server/tools.d.ts.map +1 -0
  176. package/dist/server/tools.js +347 -0
  177. package/dist/server/toolsEndpoint.d.ts +32 -0
  178. package/dist/server/toolsEndpoint.d.ts.map +1 -0
  179. package/dist/server/toolsEndpoint.js +237 -0
  180. package/dist/tanstack-start/index.d.ts +9 -0
  181. package/dist/tanstack-start/index.d.ts.map +1 -0
  182. package/dist/tanstack-start/index.js +29 -0
  183. package/dist/testing/index.d.ts +93 -0
  184. package/dist/testing/index.d.ts.map +1 -0
  185. package/dist/testing/index.js +156 -0
  186. package/package.json +42 -8
  187. package/dist/server/mcp.d.ts +0 -66
  188. package/dist/server/mcp.d.ts.map +0 -1
  189. package/dist/server/mcp.js +0 -147
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The rule for a workspace's name: what the Gateway's setup claim gives
3
+ * the first organization, what a personal organization is called, and
4
+ * what a rename takes (Manage workspace → Rename, `everyapp workspace
5
+ * rename`). The Gateway and the CLI share it so a name the CLI writes is
6
+ * one the Gateway would have accepted. A name is user input that reaches
7
+ * other people: the invitation emails it sends, and every member's
8
+ * organization switcher.
9
+ */
10
+ export declare const MAX_ORGANIZATION_NAME_LENGTH = 64;
11
+ /**
12
+ * The name, trimmed and with its runs of whitespace made single spaces, or
13
+ * null when it is empty, longer than 64 characters, or has a control or
14
+ * invisible formatting character (line breaks, bidirectional overrides,
15
+ * zero-width characters) anywhere in it.
16
+ */
17
+ export declare function validOrganizationName(raw: string): string | null;
18
+ //# sourceMappingURL=organizationName.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"organizationName.d.ts","sourceRoot":"","sources":["../../src/internal/organizationName.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,eAAO,MAAM,4BAA4B,KAAK,CAAC;AAE/C;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKhE"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * The rule for a workspace's name: what the Gateway's setup claim gives
3
+ * the first organization, what a personal organization is called, and
4
+ * what a rename takes (Manage workspace → Rename, `everyapp workspace
5
+ * rename`). The Gateway and the CLI share it so a name the CLI writes is
6
+ * one the Gateway would have accepted. A name is user input that reaches
7
+ * other people: the invitation emails it sends, and every member's
8
+ * organization switcher.
9
+ */
10
+ export const MAX_ORGANIZATION_NAME_LENGTH = 64;
11
+ /**
12
+ * The name, trimmed and with its runs of whitespace made single spaces, or
13
+ * null when it is empty, longer than 64 characters, or has a control or
14
+ * invisible formatting character (line breaks, bidirectional overrides,
15
+ * zero-width characters) anywhere in it.
16
+ */
17
+ export function validOrganizationName(raw) {
18
+ if (/[\p{Cc}\p{Cf}\u2028\u2029]/u.test(raw))
19
+ return null;
20
+ const name = raw.trim().replace(/\s+/g, " ");
21
+ if (!name || [...name].length > MAX_ORGANIZATION_NAME_LENGTH)
22
+ return null;
23
+ return name;
24
+ }
@@ -6,25 +6,108 @@
6
6
  * and gateway-side JWT minters shared by the platform packages.
7
7
  */
8
8
  import { type JWTPayload } from "jose";
9
+ import type { ToolCallClaim } from "./tools.js";
9
10
  export declare const IDENTITY_ALG = "RS256";
10
11
  export declare const IDENTITY_KEY_ID = "everyapp-identity";
11
12
  export declare const IDENTITY_DEV_KEY_ID = "everyapp-identity-dev";
13
+ /**
14
+ * The only issuer a dev-kid token may name. The same value as
15
+ * `@every-app/sdk/dev`'s, kept apart so the Worker never loads the module
16
+ * `cloudflare.config.ts` does (a test pins the two together).
17
+ */
18
+ export declare const DEV_ISSUER = "https://gateway.dev.localhost";
12
19
  export declare const IDENTITY_HEADER = "x-everyapp-identity";
13
20
  export declare const PUBLIC_HEADER = "x-everyapp-public";
21
+ /**
22
+ * Carries the gateway's system token on its own calls to an app (the tools
23
+ * catalog fetch). Never an identity: no user, and it only opens the endpoint
24
+ * named by its `purpose` claim.
25
+ */
26
+ export declare const SYSTEM_HEADER = "x-everyapp-system";
27
+ /**
28
+ * On a refusal the AppGateway binding makes itself (the app's manifest lacks
29
+ * the capability, the gateway holds no key), as opposed to the provider's
30
+ * own answer passed through: the refusal's code, also in the JSON body.
31
+ */
32
+ export declare const GATEWAY_ERROR_HEADER = "x-everyapp-error";
33
+ /**
34
+ * On a shared app's call to the AppGateway binding for work no request
35
+ * started (a cron, a Workflow step): the organization the work is for. The
36
+ * gateway believes it only from a shared app's Worker, and only for an
37
+ * active organization with a live member; an organization's own app may
38
+ * only name its own. The perimeter strips it, with every `x-everyapp-*`,
39
+ * from what browsers send.
40
+ */
41
+ export declare const ORG_HEADER = "x-everyapp-org";
42
+ /**
43
+ * Which connection an app's call to an OAuth provider uses: the person's
44
+ * (`user`, the default when a person is behind the call) or the
45
+ * organization's (`organization`, the default for background work),
46
+ * docs/design/2026-10-oauth-providers.md section 7. Set by
47
+ * `integrationFetch({ account })`; the gateway reads it on the held-token
48
+ * branch and ignores it elsewhere.
49
+ */
50
+ export declare const ACCOUNT_HEADER = "x-everyapp-account";
51
+ /** The values {@link ACCOUNT_HEADER} may carry. */
52
+ export type ConnectionAccount = "user" | "organization";
14
53
  /** 120-second lifetime — caps revocation staleness while surviving clock skew. */
15
54
  export declare const IDENTITY_TTL_SECONDS = 120;
16
- /** Env var carrying the app id used as the expected identity audience. */
55
+ /** System tokens are minted per call and live at most a minute. */
56
+ export declare const SYSTEM_TOKEN_TTL_SECONDS = 60;
57
+ /** Env var carrying the app's manifest id. */
17
58
  export declare const APP_ID_ENV = "EVERYAPP_APP_ID";
59
+ /**
60
+ * Env var carrying the expected identity audience: the app's Worker name,
61
+ * which the gateway stamps as `aud` on every token it mints for the app. Two
62
+ * Workers of one app id (two organizations' copies) never accept each
63
+ * other's tokens.
64
+ */
65
+ export declare const AUDIENCE_ENV = "EVERYAPP_AUDIENCE";
18
66
  /** Default env var carrying a JSON array of SPKI PEM public keys. */
19
67
  export declare const PUBLIC_KEYS_ENV = "EVERYAPP_IDENTITY_PUBLIC_KEYS";
20
68
  /** Env var carrying the expected gateway issuer for user identity verification. */
21
69
  export declare const ISSUER_ENV = "EVERYAPP_IDENTITY_ISSUER";
70
+ /**
71
+ * Env var set to `1` on a shared app's Workers (one Worker for every
72
+ * organization): a gateway call from them must say whom it is for.
73
+ */
74
+ export declare const SHARED_ENV = "EVERYAPP_SHARED";
22
75
  /** When set to `1` or `true` in the worker env, the dev identity kid is accepted. */
23
76
  export declare const DEV_ENV = "EVERYAPP_DEV";
77
+ /**
78
+ * The organization an app's Worker is pinned to (a secret the deploy sends;
79
+ * in development the stub gateway's organization). `everyApp()` refuses an
80
+ * identity for any other organization; absent on a shared app's Workers.
81
+ */
82
+ export declare const ORG_ID_ENV = "EVERY_APP_ORG_ID";
83
+ /**
84
+ * The organization the dev gateway's seeded user belongs to. The same value
85
+ * as `@every-app/sdk/dev`'s, kept apart like {@link DEV_ISSUER} (the same
86
+ * test pins the two together).
87
+ */
88
+ export declare const DEV_ORG_ID = "dev-org";
24
89
  /** `sub` claim the gateway mints public-route markers with. */
25
90
  export declare const PUBLIC_MARKER_SUB = "public";
91
+ /** `sub` claim of gateway system tokens. */
92
+ export declare const SYSTEM_TOKEN_SUB = "system";
93
+ /**
94
+ * Linked dev (`everyapp dev --gateway`, docs/design/linked-dev.md): the
95
+ * dev Worker's env names the gateway-lite's loopback forwarder and the
96
+ * run's nonce, and the SDK builds a `{ fetch }` in place of the missing
97
+ * `EVERY_APP_GATEWAY` binding from them. Set by `everyAppWorker()` in a
98
+ * development build from the process environment `everyapp dev` starts
99
+ * the app with; never deployed.
100
+ */
101
+ export declare const LINKED_DEV_URL_ENV = "EVERYAPP_LINKED_DEV_URL";
102
+ export declare const LINKED_DEV_NONCE_ENV = "EVERYAPP_LINKED_DEV_NONCE";
103
+ /** The header the forwarder requires, with the run's nonce: no simple cross-origin request can send it. */
104
+ export declare const LINKED_DEV_HEADER = "x-everyapp-linked-dev";
105
+ /** Where the gateway-lite serves the forwarder, under the app's own host. */
106
+ export declare const LINKED_DEV_FORWARD_PATH = "/__everyapp/gateway";
26
107
  export type IdentityChannel = "web" | "api" | "mcp" | "agent";
27
- export type IdentityTokenType = "user" | "public";
108
+ export type IdentityTokenType = "user" | "public" | "system";
109
+ /** What a system token may open. One purpose per token. */
110
+ export type SystemTokenPurpose = "tools.list";
28
111
  /** The actor on whose behalf the request is made (user, MCP client, agent). */
29
112
  export interface IdentityActor {
30
113
  sub: string;
@@ -34,28 +117,66 @@ export interface IdentitySubject {
34
117
  email: string;
35
118
  orgId: string;
36
119
  orgRole: string;
120
+ /**
121
+ * The organization's name as its owners set it (`org_name`), so an app
122
+ * can show "Acme" rather than an id. Left out when the minter has none.
123
+ */
124
+ orgName?: string;
37
125
  }
126
+ /**
127
+ * A member's role in the organization, as the identity token carries it.
128
+ * Owners and admins manage; anything the Gateway might mint that an app
129
+ * doesn't know is read as `member`.
130
+ */
131
+ export type OrgRole = "owner" | "admin" | "member";
132
+ /** `role` as an {@link OrgRole}: `owner` and `admin` as they are, anything else `member`. */
133
+ export declare function toOrgRole(role: unknown): OrgRole;
134
+ /** Whether `user` manages the organization: an owner or an admin. */
135
+ export declare function isAdmin(user: {
136
+ orgRole: OrgRole | string;
137
+ }): boolean;
38
138
  export interface EveryAppUser {
39
139
  /** User id (the `sub` claim). */
40
140
  id: string;
41
141
  email: string;
42
142
  orgId: string;
43
- orgRole: string;
143
+ orgRole: OrgRole;
144
+ /**
145
+ * The organization's display name (the `org_name` claim), as its owners
146
+ * set it: trimmed, at most 64 characters, no control characters. Show
147
+ * it; never key data by it (names change, `orgId` doesn't). Undefined
148
+ * when the token carries none.
149
+ */
150
+ orgName?: string;
44
151
  channel: IdentityChannel;
45
152
  /** The acting principal (user, or `mcp:<client>` / agent). */
46
153
  actor: IdentityActor;
47
154
  scopes: string[];
48
155
  jti: string;
156
+ /**
157
+ * Set only on an MCP tool call (`channel: "mcp"`): the one call this
158
+ * identity was minted for.
159
+ */
160
+ toolCall?: ToolCallClaim;
49
161
  }
50
162
  export interface IdentityClaims extends JWTPayload {
51
163
  typ: "user";
52
164
  email: string;
53
165
  org_id: string;
54
166
  org_role: string;
167
+ /** The organization's display name; absent when the minter had none. */
168
+ org_name?: string;
55
169
  chan: IdentityChannel;
56
170
  act: IdentityActor;
57
171
  scopes: string[];
58
172
  jti: string;
173
+ /** Tool-call binding; only the gateway's ToolBus mints it. */
174
+ tc?: ToolCallClaim;
175
+ }
176
+ export interface SystemClaims extends JWTPayload {
177
+ typ: "system";
178
+ purpose: SystemTokenPurpose;
179
+ jti: string;
59
180
  }
60
181
  export interface PublicMarkerClaims extends JWTPayload {
61
182
  typ: "public";
@@ -69,11 +190,18 @@ export declare function identitySubjectToClaims(subject: IdentitySubject, opts:
69
190
  channel?: IdentityChannel;
70
191
  actor?: IdentityActor;
71
192
  scopes?: string[];
193
+ toolCall?: ToolCallClaim;
72
194
  jti: string;
73
195
  }): IdentityClaims;
74
196
  export declare function identityClaimsToEveryAppUser(payload: JWTPayload): EveryAppUser;
75
197
  export declare function publicMarkerClaims(jti: string): PublicMarkerClaims;
76
198
  export declare function assertPublicMarkerClaims(payload: JWTPayload): void;
199
+ /**
200
+ * A system token opens exactly one endpoint and lives at most
201
+ * {@link SYSTEM_TOKEN_TTL_SECONDS}: a leaked one is short-lived and useless
202
+ * anywhere else.
203
+ */
204
+ export declare function assertSystemClaims(payload: JWTPayload, purpose: SystemTokenPurpose): SystemClaims;
77
205
  export interface MintIdentityOptions {
78
206
  subject: IdentitySubject;
79
207
  /** The app id this token is scoped to — becomes the `aud` claim. */
@@ -82,6 +210,8 @@ export interface MintIdentityOptions {
82
210
  channel?: IdentityChannel;
83
211
  actor?: IdentityActor;
84
212
  scopes?: string[];
213
+ /** Bind the token to one MCP tool call (`tc` claim). ToolBus only. */
214
+ toolCall?: ToolCallClaim;
85
215
  ttlSeconds?: number;
86
216
  now?: number;
87
217
  /** Header kid. Defaults to the production kid; dev mints with the dev kid. */
@@ -108,4 +238,21 @@ export interface MintPublicMarkerOptions {
108
238
  * an identity token.
109
239
  */
110
240
  export declare function mintPublicMarkerJwt(privateKeyPem: string, opts: MintPublicMarkerOptions): Promise<string>;
241
+ export interface MintSystemTokenOptions {
242
+ /** The app id the token is for — becomes the `aud` claim. */
243
+ audience: string;
244
+ issuer: string;
245
+ purpose: SystemTokenPurpose;
246
+ /** At most {@link SYSTEM_TOKEN_TTL_SECONDS}. */
247
+ ttlSeconds?: number;
248
+ now?: number;
249
+ /** Header kid. Defaults to the production kid; dev mints with the dev kid. */
250
+ keyId?: string;
251
+ }
252
+ /**
253
+ * Mint the gateway's system token for `x-everyapp-system`: no user, one
254
+ * purpose, one app, one minute. The SDK only accepts it on the endpoint its
255
+ * purpose names, and never as an identity.
256
+ */
257
+ export declare function mintSystemJwt(privateKeyPem: string, opts: MintSystemTokenOptions): Promise<string>;
111
258
  //# sourceMappingURL=protocol.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/internal/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAwB,KAAK,UAAU,EAAE,MAAM,MAAM,CAAC;AAE7D,eAAO,MAAM,YAAY,UAAU,CAAC;AACpC,eAAO,MAAM,eAAe,sBAAsB,CAAC;AACnD,eAAO,MAAM,mBAAmB,0BAA0B,CAAC;AAC3D,eAAO,MAAM,eAAe,wBAAwB,CAAC;AACrD,eAAO,MAAM,aAAa,sBAAsB,CAAC;AACjD,kFAAkF;AAClF,eAAO,MAAM,oBAAoB,MAAM,CAAC;AACxC,0EAA0E;AAC1E,eAAO,MAAM,UAAU,oBAAoB,CAAC;AAC5C,qEAAqE;AACrE,eAAO,MAAM,eAAe,kCAAkC,CAAC;AAC/D,mFAAmF;AACnF,eAAO,MAAM,UAAU,6BAA6B,CAAC;AACrD,qFAAqF;AACrF,eAAO,MAAM,OAAO,iBAAiB,CAAC;AACtC,+DAA+D;AAC/D,eAAO,MAAM,iBAAiB,WAAW,CAAC;AAE1C,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,OAAO,CAAC;AAC9D,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,QAAQ,CAAC;AAElD,+EAA+E;AAC/E,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,iCAAiC;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,eAAe,CAAC;IACzB,8DAA8D;IAC9D,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,cAAe,SAAQ,UAAU;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,eAAe,CAAC;IACtB,GAAG,EAAE,aAAa,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,kBAAmB,SAAQ,UAAU;IACpD,GAAG,EAAE,QAAQ,CAAC;IACd,GAAG,EAAE,IAAI,CAAC;IACV,GAAG,EAAE,MAAM,CAAC;CACb;AAED,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;CAI5B;AAED,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,eAAe,EACxB,IAAI,EAAE;IACJ,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;CACb,GACA,cAAc,CAWhB;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,UAAU,GAClB,YAAY,CA4Bd;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,CAElE;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,CAOlE;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,eAAe,CAAC;IACzB,oEAAoE;IACpE,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAgBD;;;GAGG;AACH,wBAAsB,eAAe,CACnC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,MAAM,CAAC,CAwBjB;AAED,MAAM,WAAW,uBAAuB;IACtC,qEAAqE;IACrE,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,uBAAuB,GAC5B,OAAO,CAAC,MAAM,CAAC,CAgBjB"}
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/internal/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAwB,KAAK,UAAU,EAAE,MAAM,MAAM,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,eAAO,MAAM,YAAY,UAAU,CAAC;AACpC,eAAO,MAAM,eAAe,sBAAsB,CAAC;AACnD,eAAO,MAAM,mBAAmB,0BAA0B,CAAC;AAC3D;;;;GAIG;AACH,eAAO,MAAM,UAAU,kCAAkC,CAAC;AAC1D,eAAO,MAAM,eAAe,wBAAwB,CAAC;AACrD,eAAO,MAAM,aAAa,sBAAsB,CAAC;AACjD;;;;GAIG;AACH,eAAO,MAAM,aAAa,sBAAsB,CAAC;AACjD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,qBAAqB,CAAC;AACvD;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,mBAAmB,CAAC;AAC3C;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,uBAAuB,CAAC;AACnD,mDAAmD;AACnD,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,cAAc,CAAC;AACxD,kFAAkF;AAClF,eAAO,MAAM,oBAAoB,MAAM,CAAC;AACxC,mEAAmE;AACnE,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAC3C,8CAA8C;AAC9C,eAAO,MAAM,UAAU,oBAAoB,CAAC;AAC5C;;;;;GAKG;AACH,eAAO,MAAM,YAAY,sBAAsB,CAAC;AAChD,qEAAqE;AACrE,eAAO,MAAM,eAAe,kCAAkC,CAAC;AAC/D,mFAAmF;AACnF,eAAO,MAAM,UAAU,6BAA6B,CAAC;AACrD;;;GAGG;AACH,eAAO,MAAM,UAAU,oBAAoB,CAAC;AAC5C,qFAAqF;AACrF,eAAO,MAAM,OAAO,iBAAiB,CAAC;AACtC;;;;GAIG;AACH,eAAO,MAAM,UAAU,qBAAqB,CAAC;AAC7C;;;;GAIG;AACH,eAAO,MAAM,UAAU,YAAY,CAAC;AACpC,+DAA+D;AAC/D,eAAO,MAAM,iBAAiB,WAAW,CAAC;AAC1C,4CAA4C;AAC5C,eAAO,MAAM,gBAAgB,WAAW,CAAC;AAEzC;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,4BAA4B,CAAC;AAC5D,eAAO,MAAM,oBAAoB,8BAA8B,CAAC;AAChE,2GAA2G;AAC3G,eAAO,MAAM,iBAAiB,0BAA0B,CAAC;AACzD,6EAA6E;AAC7E,eAAO,MAAM,uBAAuB,wBAAwB,CAAC;AAE7D,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,OAAO,CAAC;AAC9D,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAC7D,2DAA2D;AAC3D,MAAM,MAAM,kBAAkB,GAAG,YAAY,CAAC;AAE9C,+EAA+E;AAC/E,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,MAAM,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEnD,6FAA6F;AAC7F,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAEhD;AAED,qEAAqE;AACrE,wBAAgB,OAAO,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAAA;CAAE,GAAG,OAAO,CAEpE;AAED,MAAM,WAAW,YAAY;IAC3B,iCAAiC;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,eAAe,CAAC;IACzB,8DAA8D;IAC9D,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ;;;OAGG;IACH,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAED,MAAM,WAAW,cAAe,SAAQ,UAAU;IAChD,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,eAAe,CAAC;IACtB,GAAG,EAAE,aAAa,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,8DAA8D;IAC9D,EAAE,CAAC,EAAE,aAAa,CAAC;CACpB;AAED,MAAM,WAAW,YAAa,SAAQ,UAAU;IAC9C,GAAG,EAAE,QAAQ,CAAC;IACd,OAAO,EAAE,kBAAkB,CAAC;IAC5B,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,kBAAmB,SAAQ,UAAU;IACpD,GAAG,EAAE,QAAQ,CAAC;IACd,GAAG,EAAE,IAAI,CAAC;IACV,GAAG,EAAE,MAAM,CAAC;CACb;AAED,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;CAI5B;AAED,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,eAAe,EACxB,IAAI,EAAE;IACJ,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;CACb,GACA,cAAc,CAehB;AAkBD,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,UAAU,GAClB,YAAY,CAqCd;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,CAElE;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,CAOlE;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,UAAU,EACnB,OAAO,EAAE,kBAAkB,GAC1B,YAAY,CAmBd;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,eAAe,CAAC;IACzB,oEAAoE;IACpE,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAgBD;;;GAGG;AACH,wBAAsB,eAAe,CACnC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,MAAM,CAAC,CAyBjB;AAED,MAAM,WAAW,uBAAuB;IACtC,qEAAqE;IACrE,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,uBAAuB,GAC5B,OAAO,CAAC,MAAM,CAAC,CAgBjB;AAED,MAAM,WAAW,sBAAsB;IACrC,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,kBAAkB,CAAC;IAC5B,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,sBAAsB,GAC3B,OAAO,CAAC,MAAM,CAAC,CA0BjB"}
@@ -9,20 +9,106 @@ import { SignJWT, importPKCS8 } from "jose";
9
9
  export const IDENTITY_ALG = "RS256";
10
10
  export const IDENTITY_KEY_ID = "everyapp-identity";
11
11
  export const IDENTITY_DEV_KEY_ID = "everyapp-identity-dev";
12
+ /**
13
+ * The only issuer a dev-kid token may name. The same value as
14
+ * `@every-app/sdk/dev`'s, kept apart so the Worker never loads the module
15
+ * `cloudflare.config.ts` does (a test pins the two together).
16
+ */
17
+ export const DEV_ISSUER = "https://gateway.dev.localhost";
12
18
  export const IDENTITY_HEADER = "x-everyapp-identity";
13
19
  export const PUBLIC_HEADER = "x-everyapp-public";
20
+ /**
21
+ * Carries the gateway's system token on its own calls to an app (the tools
22
+ * catalog fetch). Never an identity: no user, and it only opens the endpoint
23
+ * named by its `purpose` claim.
24
+ */
25
+ export const SYSTEM_HEADER = "x-everyapp-system";
26
+ /**
27
+ * On a refusal the AppGateway binding makes itself (the app's manifest lacks
28
+ * the capability, the gateway holds no key), as opposed to the provider's
29
+ * own answer passed through: the refusal's code, also in the JSON body.
30
+ */
31
+ export const GATEWAY_ERROR_HEADER = "x-everyapp-error";
32
+ /**
33
+ * On a shared app's call to the AppGateway binding for work no request
34
+ * started (a cron, a Workflow step): the organization the work is for. The
35
+ * gateway believes it only from a shared app's Worker, and only for an
36
+ * active organization with a live member; an organization's own app may
37
+ * only name its own. The perimeter strips it, with every `x-everyapp-*`,
38
+ * from what browsers send.
39
+ */
40
+ export const ORG_HEADER = "x-everyapp-org";
41
+ /**
42
+ * Which connection an app's call to an OAuth provider uses: the person's
43
+ * (`user`, the default when a person is behind the call) or the
44
+ * organization's (`organization`, the default for background work),
45
+ * docs/design/2026-10-oauth-providers.md section 7. Set by
46
+ * `integrationFetch({ account })`; the gateway reads it on the held-token
47
+ * branch and ignores it elsewhere.
48
+ */
49
+ export const ACCOUNT_HEADER = "x-everyapp-account";
14
50
  /** 120-second lifetime — caps revocation staleness while surviving clock skew. */
15
51
  export const IDENTITY_TTL_SECONDS = 120;
16
- /** Env var carrying the app id used as the expected identity audience. */
52
+ /** System tokens are minted per call and live at most a minute. */
53
+ export const SYSTEM_TOKEN_TTL_SECONDS = 60;
54
+ /** Env var carrying the app's manifest id. */
17
55
  export const APP_ID_ENV = "EVERYAPP_APP_ID";
56
+ /**
57
+ * Env var carrying the expected identity audience: the app's Worker name,
58
+ * which the gateway stamps as `aud` on every token it mints for the app. Two
59
+ * Workers of one app id (two organizations' copies) never accept each
60
+ * other's tokens.
61
+ */
62
+ export const AUDIENCE_ENV = "EVERYAPP_AUDIENCE";
18
63
  /** Default env var carrying a JSON array of SPKI PEM public keys. */
19
64
  export const PUBLIC_KEYS_ENV = "EVERYAPP_IDENTITY_PUBLIC_KEYS";
20
65
  /** Env var carrying the expected gateway issuer for user identity verification. */
21
66
  export const ISSUER_ENV = "EVERYAPP_IDENTITY_ISSUER";
67
+ /**
68
+ * Env var set to `1` on a shared app's Workers (one Worker for every
69
+ * organization): a gateway call from them must say whom it is for.
70
+ */
71
+ export const SHARED_ENV = "EVERYAPP_SHARED";
22
72
  /** When set to `1` or `true` in the worker env, the dev identity kid is accepted. */
23
73
  export const DEV_ENV = "EVERYAPP_DEV";
74
+ /**
75
+ * The organization an app's Worker is pinned to (a secret the deploy sends;
76
+ * in development the stub gateway's organization). `everyApp()` refuses an
77
+ * identity for any other organization; absent on a shared app's Workers.
78
+ */
79
+ export const ORG_ID_ENV = "EVERY_APP_ORG_ID";
80
+ /**
81
+ * The organization the dev gateway's seeded user belongs to. The same value
82
+ * as `@every-app/sdk/dev`'s, kept apart like {@link DEV_ISSUER} (the same
83
+ * test pins the two together).
84
+ */
85
+ export const DEV_ORG_ID = "dev-org";
24
86
  /** `sub` claim the gateway mints public-route markers with. */
25
87
  export const PUBLIC_MARKER_SUB = "public";
88
+ /** `sub` claim of gateway system tokens. */
89
+ export const SYSTEM_TOKEN_SUB = "system";
90
+ /**
91
+ * Linked dev (`everyapp dev --gateway`, docs/design/linked-dev.md): the
92
+ * dev Worker's env names the gateway-lite's loopback forwarder and the
93
+ * run's nonce, and the SDK builds a `{ fetch }` in place of the missing
94
+ * `EVERY_APP_GATEWAY` binding from them. Set by `everyAppWorker()` in a
95
+ * development build from the process environment `everyapp dev` starts
96
+ * the app with; never deployed.
97
+ */
98
+ export const LINKED_DEV_URL_ENV = "EVERYAPP_LINKED_DEV_URL";
99
+ export const LINKED_DEV_NONCE_ENV = "EVERYAPP_LINKED_DEV_NONCE";
100
+ /** The header the forwarder requires, with the run's nonce: no simple cross-origin request can send it. */
101
+ export const LINKED_DEV_HEADER = "x-everyapp-linked-dev";
102
+ /** Where the gateway-lite serves the forwarder, under the app's own host. */
103
+ export const LINKED_DEV_FORWARD_PATH = "/__everyapp/gateway";
104
+ /** `role` as an {@link OrgRole}: `owner` and `admin` as they are, anything else `member`. */
105
+ export function toOrgRole(role) {
106
+ return role === "owner" || role === "admin" ? role : "member";
107
+ }
108
+ /** Whether `user` manages the organization: an owner or an admin. */
109
+ export function isAdmin(user) {
110
+ return user.orgRole === "owner" || user.orgRole === "admin";
111
+ }
26
112
  export class ProtocolClaimsError extends Error {
27
113
  constructor(message) {
28
114
  super(message);
@@ -35,12 +121,30 @@ export function identitySubjectToClaims(subject, opts) {
35
121
  email: subject.email,
36
122
  org_id: subject.orgId,
37
123
  org_role: subject.orgRole,
124
+ ...(subject.orgName ? { org_name: subject.orgName } : {}),
38
125
  chan: opts.channel ?? "web",
39
126
  act: opts.actor ?? { sub: subject.sub },
40
127
  scopes: opts.scopes ?? ["*"],
41
128
  jti: opts.jti,
129
+ ...(opts.toolCall
130
+ ? { tc: { id: opts.toolCall.id, name: opts.toolCall.name } }
131
+ : {}),
42
132
  };
43
133
  }
134
+ function parseToolCallClaim(value) {
135
+ if (value === undefined)
136
+ return undefined;
137
+ const claim = value;
138
+ if (!claim ||
139
+ typeof claim !== "object" ||
140
+ typeof claim.id !== "string" ||
141
+ typeof claim.name !== "string" ||
142
+ !claim.id ||
143
+ !claim.name) {
144
+ throw new ProtocolClaimsError("identity token has a malformed tc claim");
145
+ }
146
+ return { id: claim.id, name: claim.name };
147
+ }
44
148
  export function identityClaimsToEveryAppUser(payload) {
45
149
  if (payload.typ !== "user") {
46
150
  throw new ProtocolClaimsError("identity token has wrong typ");
@@ -52,20 +156,28 @@ export function identityClaimsToEveryAppUser(payload) {
52
156
  if (!sub || !email || !orgId || !orgRole) {
53
157
  throw new ProtocolClaimsError("identity token missing required claims");
54
158
  }
159
+ // Display only, so a token without it (or with a malformed one) is still
160
+ // an identity: the app falls back to no name.
161
+ const orgName = typeof payload.org_name === "string" && payload.org_name
162
+ ? payload.org_name
163
+ : undefined;
55
164
  const chan = payload.chan ?? "web";
56
165
  const act = payload.act ?? { sub };
57
166
  const scopes = Array.isArray(payload.scopes)
58
167
  ? payload.scopes.filter((scope) => typeof scope === "string")
59
168
  : ["*"];
169
+ const toolCall = parseToolCallClaim(payload.tc);
60
170
  return {
61
171
  id: sub,
62
172
  email,
63
173
  orgId,
64
- orgRole,
174
+ orgRole: toOrgRole(orgRole),
175
+ ...(orgName ? { orgName } : {}),
65
176
  channel: chan,
66
177
  actor: { sub: act.sub ?? sub },
67
178
  scopes,
68
179
  jti: payload.jti ?? "",
180
+ ...(toolCall ? { toolCall } : {}),
69
181
  };
70
182
  }
71
183
  export function publicMarkerClaims(jti) {
@@ -79,6 +191,25 @@ export function assertPublicMarkerClaims(payload) {
79
191
  throw new ProtocolClaimsError("token is not a public-route marker");
80
192
  }
81
193
  }
194
+ /**
195
+ * A system token opens exactly one endpoint and lives at most
196
+ * {@link SYSTEM_TOKEN_TTL_SECONDS}: a leaked one is short-lived and useless
197
+ * anywhere else.
198
+ */
199
+ export function assertSystemClaims(payload, purpose) {
200
+ if (payload.typ !== "system" || payload.sub !== SYSTEM_TOKEN_SUB) {
201
+ throw new ProtocolClaimsError("token is not a system token");
202
+ }
203
+ if (payload.purpose !== purpose) {
204
+ throw new ProtocolClaimsError(`system token purpose "${String(payload.purpose)}" is not "${purpose}"`);
205
+ }
206
+ if (typeof payload.iat !== "number" ||
207
+ typeof payload.exp !== "number" ||
208
+ payload.exp - payload.iat > SYSTEM_TOKEN_TTL_SECONDS) {
209
+ throw new ProtocolClaimsError(`system token must expire within ${SYSTEM_TOKEN_TTL_SECONDS}s of issue`);
210
+ }
211
+ return payload;
212
+ }
82
213
  let cachedPrivateKey = null;
83
214
  async function loadPrivateKey(privateKeyPem) {
84
215
  const pem = privateKeyPem.replace(/\\n/g, "\n");
@@ -102,6 +233,7 @@ export async function mintIdentityJwt(privateKeyPem, opts) {
102
233
  channel: opts.channel,
103
234
  actor: opts.actor,
104
235
  scopes: opts.scopes,
236
+ toolCall: opts.toolCall,
105
237
  jti,
106
238
  }))
107
239
  .setProtectedHeader({
@@ -137,3 +269,32 @@ export async function mintPublicMarkerJwt(privateKeyPem, opts) {
137
269
  .setExpirationTime(nowSec + ttl)
138
270
  .sign(key);
139
271
  }
272
+ /**
273
+ * Mint the gateway's system token for `x-everyapp-system`: no user, one
274
+ * purpose, one app, one minute. The SDK only accepts it on the endpoint its
275
+ * purpose names, and never as an identity.
276
+ */
277
+ export async function mintSystemJwt(privateKeyPem, opts) {
278
+ const ttl = opts.ttlSeconds ?? SYSTEM_TOKEN_TTL_SECONDS;
279
+ if (ttl <= 0 || ttl > SYSTEM_TOKEN_TTL_SECONDS) {
280
+ throw new RangeError(`system tokens live at most ${SYSTEM_TOKEN_TTL_SECONDS}s (got ${ttl})`);
281
+ }
282
+ const key = await loadPrivateKey(privateKeyPem);
283
+ const nowSec = Math.floor((opts.now ?? Date.now()) / 1000);
284
+ const claims = {
285
+ typ: "system",
286
+ purpose: opts.purpose,
287
+ jti: crypto.randomUUID(),
288
+ };
289
+ return new SignJWT(claims)
290
+ .setProtectedHeader({
291
+ alg: IDENTITY_ALG,
292
+ kid: opts.keyId ?? IDENTITY_KEY_ID,
293
+ })
294
+ .setIssuer(opts.issuer)
295
+ .setSubject(SYSTEM_TOKEN_SUB)
296
+ .setAudience(opts.audience)
297
+ .setIssuedAt(nowSec)
298
+ .setExpirationTime(nowSec + ttl)
299
+ .sign(key);
300
+ }
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Provider apps, "MCP apps" to the person: a data provider (DataForSEO
3
+ * today) offered to members as an app of the Gateway's own, with no page
4
+ * and no Worker to deploy. The operator turns it on (`everyapp mcp on
5
+ * <id>`) and sets the provider's key as a Gateway setting; the Gateway then
6
+ * serves the provider's tools on its `/mcp` under `<id>_<tool>` names, with
7
+ * the key never leaving the Gateway, every call attributed to the member
8
+ * who made it, counted and audited like an app's capability calls. The
9
+ * launcher lists it under "MCP apps" and its card opens the "Use it from
10
+ * your agent" dialog instead of a page (docs/design/2026-10-mcp-apps-ui.md).
11
+ *
12
+ * A provider app is an `apps` row of tier {@link PROVIDER_APP_TIER} with no
13
+ * hostname and no Worker name: the perimeter never routes it, and the
14
+ * Gateway reaches its tools in-process rather than over a service binding.
15
+ * Its manifest is generated here, so the settings model
16
+ * (./appSettings.ts) reads the provider's key as a required Gateway setting
17
+ * like any app's capability. The registry rules that write the row are in
18
+ * `@every-app/perimeter/registry` (providerApps.ts); the Gateway serves it
19
+ * from `apps/every-app-gateway/src/server/provider-apps/`.
20
+ */
21
+ import { type ApiKeyCapabilityId } from "./capabilities.js";
22
+ /** The `apps.tier` of a provider app: no Worker, served by the Gateway itself. */
23
+ export declare const PROVIDER_APP_TIER = "provider";
24
+ export interface ProviderAppDefinition {
25
+ /** The app id (its slug and tool-name prefix): lowercase, no underscore. */
26
+ id: string;
27
+ /** What Admin → Apps and the launcher call it. */
28
+ name: string;
29
+ /** What it is for, as the app library and `everyapp_list_apps` tell it. */
30
+ description: string;
31
+ /**
32
+ * The `api_key` capability whose Gateway setting holds the key and whose
33
+ * proxy rules (hosts, methods, account-wide paths) every tool call obeys.
34
+ */
35
+ capability: ApiKeyCapabilityId;
36
+ /** Why the app lists the capability: the manifest entry's `why`. */
37
+ why: string;
38
+ /**
39
+ * What to say to an agent to try it, after "Use <name> to": the "Use it
40
+ * from your agent" dialog's example sentence.
41
+ */
42
+ example: string;
43
+ }
44
+ export declare const PROVIDER_APPS: {
45
+ readonly dataforseo: {
46
+ readonly id: "dataforseo";
47
+ readonly name: "DataForSEO";
48
+ readonly description: "SEO data for your agent: keyword metrics and suggestions, live Google results, domain rankings, competitors and backlinks, through the Gateway's DataForSEO key.";
49
+ readonly capability: "dataforseo";
50
+ readonly why: "Serves DataForSEO's keyword, search-result, domain and backlink data to members' AI clients.";
51
+ readonly example: "find keyword ideas for a page about running shoes";
52
+ };
53
+ };
54
+ export type ProviderAppId = keyof typeof PROVIDER_APPS;
55
+ /** The provider app ids, in a stable order. */
56
+ export declare const PROVIDER_APP_IDS: ProviderAppId[];
57
+ export declare function isProviderAppId(id: string): id is ProviderAppId;
58
+ /** The Gateway setting that holds a provider app's key (`DATAFORSEO_API_KEY`). */
59
+ export declare function providerAppKeySetting(id: ProviderAppId): string;
60
+ /**
61
+ * The manifest a provider app's registry row stores: what a deployed app
62
+ * would declare to use the same capability, so Admin → Apps, the settings
63
+ * model and the integration proxy read it like any app's. Read-only
64
+ * access: every provider app only reads data.
65
+ */
66
+ export declare function providerAppManifest(id: ProviderAppId): {
67
+ id: string;
68
+ name: string;
69
+ description: string;
70
+ capabilities: Record<string, {
71
+ access: "read";
72
+ why: string;
73
+ }>;
74
+ };
75
+ //# sourceMappingURL=providerApps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providerApps.d.ts","sourceRoot":"","sources":["../../src/internal/providerApps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,mBAAmB,CAAC;AAE3B,kFAAkF;AAClF,eAAO,MAAM,iBAAiB,aAAa,CAAC;AAE5C,MAAM,WAAW,qBAAqB;IACpC,4EAA4E;IAC5E,EAAE,EAAE,MAAM,CAAC;IACX,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,WAAW,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,UAAU,EAAE,kBAAkB,CAAC;IAC/B,oEAAoE;IACpE,GAAG,EAAE,MAAM,CAAC;IACZ;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,aAAa;;;;;;;;;CAUgC,CAAC;AAE3D,MAAM,MAAM,aAAa,GAAG,MAAM,OAAO,aAAa,CAAC;AAEvD,+CAA+C;AAC/C,eAAO,MAAM,gBAAgB,EAEjB,aAAa,EAAE,CAAC;AAE5B,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,EAAE,IAAI,aAAa,CAE/D;AAED,kFAAkF;AAClF,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,aAAa,GAAG,MAAM,CAE/D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,aAAa,GAAG;IACtD,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC/D,CAUA"}