@every-app/sdk 0.1.14 → 0.2.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 (82) hide show
  1. package/dist/internal/identity.d.ts +73 -0
  2. package/dist/internal/identity.d.ts.map +1 -0
  3. package/dist/internal/identity.js +192 -0
  4. package/dist/internal/index.d.ts +3 -0
  5. package/dist/internal/index.d.ts.map +1 -0
  6. package/dist/internal/index.js +2 -0
  7. package/dist/internal/protocol.d.ts +111 -0
  8. package/dist/internal/protocol.d.ts.map +1 -0
  9. package/dist/internal/protocol.js +139 -0
  10. package/dist/server/everyApp.d.ts +55 -0
  11. package/dist/server/everyApp.d.ts.map +1 -0
  12. package/dist/server/everyApp.js +121 -0
  13. package/dist/server/gatewayFetch.d.ts +21 -0
  14. package/dist/server/gatewayFetch.d.ts.map +1 -0
  15. package/dist/server/gatewayFetch.js +70 -0
  16. package/dist/server/index.d.ts +9 -0
  17. package/dist/server/index.d.ts.map +1 -0
  18. package/dist/server/index.js +8 -0
  19. package/dist/server/mcp.d.ts +66 -0
  20. package/dist/server/mcp.d.ts.map +1 -0
  21. package/dist/server/mcp.js +147 -0
  22. package/package.json +20 -43
  23. package/dist/cloudflare/getLocalD1Url.d.ts +0 -2
  24. package/dist/cloudflare/getLocalD1Url.d.ts.map +0 -1
  25. package/dist/cloudflare/getLocalD1Url.js +0 -40
  26. package/dist/cloudflare/index.d.ts +0 -2
  27. package/dist/cloudflare/index.d.ts.map +0 -1
  28. package/dist/cloudflare/index.js +0 -1
  29. package/dist/cloudflare/lazyInit.d.ts +0 -22
  30. package/dist/cloudflare/lazyInit.d.ts.map +0 -1
  31. package/dist/cloudflare/lazyInit.js +0 -65
  32. package/dist/cloudflare/server/gateway.d.ts +0 -29
  33. package/dist/cloudflare/server/gateway.d.ts.map +0 -1
  34. package/dist/cloudflare/server/gateway.js +0 -69
  35. package/dist/cloudflare/server/index.d.ts +0 -3
  36. package/dist/cloudflare/server/index.d.ts.map +0 -1
  37. package/dist/cloudflare/server/index.js +0 -2
  38. package/dist/core/authenticatedFetch.d.ts +0 -9
  39. package/dist/core/authenticatedFetch.d.ts.map +0 -1
  40. package/dist/core/authenticatedFetch.js +0 -31
  41. package/dist/core/index.d.ts +0 -4
  42. package/dist/core/index.d.ts.map +0 -1
  43. package/dist/core/index.js +0 -2
  44. package/dist/core/sessionManager.d.ts +0 -58
  45. package/dist/core/sessionManager.d.ts.map +0 -1
  46. package/dist/core/sessionManager.js +0 -357
  47. package/dist/shared/bypassGatewayLocalOnly.d.ts +0 -15
  48. package/dist/shared/bypassGatewayLocalOnly.d.ts.map +0 -1
  49. package/dist/shared/bypassGatewayLocalOnly.js +0 -45
  50. package/dist/shared/parseMessagePayload.d.ts +0 -3
  51. package/dist/shared/parseMessagePayload.d.ts.map +0 -1
  52. package/dist/shared/parseMessagePayload.js +0 -18
  53. package/dist/tanstack/EmbeddedAppProvider.d.ts +0 -30
  54. package/dist/tanstack/EmbeddedAppProvider.d.ts.map +0 -1
  55. package/dist/tanstack/EmbeddedAppProvider.js +0 -57
  56. package/dist/tanstack/GatewayRequiredError.d.ts +0 -20
  57. package/dist/tanstack/GatewayRequiredError.d.ts.map +0 -1
  58. package/dist/tanstack/GatewayRequiredError.js +0 -91
  59. package/dist/tanstack/_internal/useEveryAppSession.d.ts +0 -18
  60. package/dist/tanstack/_internal/useEveryAppSession.d.ts.map +0 -1
  61. package/dist/tanstack/_internal/useEveryAppSession.js +0 -47
  62. package/dist/tanstack/index.d.ts +0 -4
  63. package/dist/tanstack/index.d.ts.map +0 -1
  64. package/dist/tanstack/index.js +0 -3
  65. package/dist/tanstack/server/authConfig.d.ts +0 -3
  66. package/dist/tanstack/server/authConfig.d.ts.map +0 -1
  67. package/dist/tanstack/server/authConfig.js +0 -13
  68. package/dist/tanstack/server/authenticateRequest.d.ts +0 -31
  69. package/dist/tanstack/server/authenticateRequest.d.ts.map +0 -1
  70. package/dist/tanstack/server/authenticateRequest.js +0 -154
  71. package/dist/tanstack/server/index.d.ts +0 -4
  72. package/dist/tanstack/server/index.d.ts.map +0 -1
  73. package/dist/tanstack/server/index.js +0 -2
  74. package/dist/tanstack/server/types.d.ts +0 -5
  75. package/dist/tanstack/server/types.d.ts.map +0 -1
  76. package/dist/tanstack/server/types.js +0 -1
  77. package/dist/tanstack/useEveryAppRouter.d.ts +0 -7
  78. package/dist/tanstack/useEveryAppRouter.d.ts.map +0 -1
  79. package/dist/tanstack/useEveryAppRouter.js +0 -66
  80. package/dist/tanstack/useSessionTokenClientMiddleware.d.ts +0 -2
  81. package/dist/tanstack/useSessionTokenClientMiddleware.d.ts.map +0 -1
  82. package/dist/tanstack/useSessionTokenClientMiddleware.js +0 -29
@@ -0,0 +1,73 @@
1
+ import { APP_ID_ENV, DEV_ENV, IDENTITY_ALG, IDENTITY_DEV_KEY_ID, IDENTITY_HEADER, IDENTITY_KEY_ID, ISSUER_ENV, PUBLIC_HEADER, PUBLIC_KEYS_ENV, PUBLIC_MARKER_SUB, type EveryAppUser, type IdentityChannel } from "./protocol.js";
2
+ export { APP_ID_ENV, DEV_ENV, IDENTITY_ALG, IDENTITY_DEV_KEY_ID, IDENTITY_HEADER, IDENTITY_KEY_ID, ISSUER_ENV, PUBLIC_HEADER, PUBLIC_KEYS_ENV, PUBLIC_MARKER_SUB, type EveryAppUser, type IdentityChannel, };
3
+ export declare class IdentityError extends Error {
4
+ readonly status = 401;
5
+ constructor(message: string);
6
+ }
7
+ export declare class ConfigurationError extends Error {
8
+ readonly status = 500;
9
+ constructor(message: string);
10
+ }
11
+ /**
12
+ * Parse the public key set from an env var value. Accepts a JSON array of PEM
13
+ * strings, or a single PEM string. Returns at least one key or throws.
14
+ */
15
+ export declare function parsePublicKeys(envValue: string | undefined | null): string[];
16
+ export interface VerifyOptions {
17
+ /** SPKI PEM public keys (current + next). */
18
+ publicKeys: string[];
19
+ /** Expected `aud` — this app's id. */
20
+ audience: string;
21
+ /** Expected issuer (the gateway URL). Required for user identities. */
22
+ issuer?: string;
23
+ /**
24
+ * Accept the dev identity kid ({@link IDENTITY_DEV_KEY_ID}). Set ONLY in
25
+ * local dev (driven by the {@link DEV_ENV} worker env var). Never true in
26
+ * production.
27
+ */
28
+ allowDevIdentities?: boolean;
29
+ /** Override for tests. */
30
+ now?: number;
31
+ }
32
+ /**
33
+ * Verify an identity JWT fail-closed. Throws {@link IdentityError} on any
34
+ * problem (bad alg/kid, `none`, wrong key, expired, wrong audience, missing
35
+ * claims).
36
+ */
37
+ export declare function verifyIdentityJwt(token: string, options: VerifyOptions): Promise<EveryAppUser>;
38
+ /**
39
+ * Verify a public-route marker (the value of `x-everyapp-public`). The marker
40
+ * is a gateway-signed, app-scoped JWT with `pub: true` and `typ: "public"` —
41
+ * a bare header is NEVER a trust source, so a re-exposed app worker cannot be
42
+ * flipped into public mode by anyone who can type a header. Throws on any
43
+ * problem.
44
+ */
45
+ export declare function verifyPublicMarkerJwt(token: string, options: VerifyOptions): Promise<void>;
46
+ export interface IdentityResult {
47
+ /** The verified user, or null for a declared public route. */
48
+ user: EveryAppUser | null;
49
+ /** True when the gateway marked this request as a public route. */
50
+ isPublic: boolean;
51
+ }
52
+ export interface RequestIdentityOptions {
53
+ audience: string;
54
+ /** Provide keys directly, or let {@link getIdentityFromRequest} read env. */
55
+ publicKeys?: string[];
56
+ /** Env bag to read {@link PUBLIC_KEYS_ENV} / {@link DEV_ENV} from. */
57
+ env?: Record<string, unknown>;
58
+ keysEnvVar?: string;
59
+ issuer?: string;
60
+ /** Force dev-kid acceptance. Defaults to reading {@link DEV_ENV} from env. */
61
+ allowDevIdentities?: boolean;
62
+ now?: number;
63
+ }
64
+ /**
65
+ * Resolve identity for an incoming proxied request. Public routes carry a
66
+ * gateway-SIGNED marker in `x-everyapp-public` and resolve to
67
+ * `{ user: null, isPublic: true }` only after the marker verifies. Everything
68
+ * else requires a valid identity JWT. Throws {@link IdentityError} on any
69
+ * problem — including a bare/forged public header — so a re-exposed worker
70
+ * fails closed.
71
+ */
72
+ export declare function getIdentityFromRequest(request: Request, options: RequestIdentityOptions): Promise<IdentityResult>;
73
+ //# sourceMappingURL=identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/internal/identity.ts"],"names":[],"mappings":"AAgBA,OAAO,EACL,UAAU,EACV,OAAO,EACP,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,UAAU,EACV,aAAa,EACb,eAAe,EACf,iBAAiB,EAIjB,KAAK,YAAY,EACjB,KAAK,eAAe,EAErB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,UAAU,EACV,OAAO,EACP,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,UAAU,EACV,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,KAAK,YAAY,EACjB,KAAK,eAAe,GACrB,CAAC;AAEF,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,MAAM,OAAO;gBACV,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,MAAM,OAAO;gBACV,OAAO,EAAE,MAAM;CAI5B;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,EAAE,CA8B7E;AAYD,MAAM,WAAW,aAAa;IAC5B,6CAA6C;IAC7C,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,0BAA0B;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,YAAY,CAAC,CAUvB;AAmED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,MAAM,WAAW,cAAc;IAC7B,8DAA8D;IAC9D,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;IAC1B,mEAAmE;IACnE,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,sEAAsE;IACtE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;GAOG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,cAAc,CAAC,CAqCzB"}
@@ -0,0 +1,192 @@
1
+ /**
2
+ * Every App identity JWT verification (the app side of the trust boundary).
3
+ *
4
+ * The gateway injects a short-lived RS256 JWT as `x-everyapp-identity`. This
5
+ * module verifies it **fail-closed**: the algorithm and key id are pinned,
6
+ * `none` is rejected, the audience must equal this app, and the verification
7
+ * key set arrives from an env var (current + next public keys) — never a
8
+ * runtime JWKS fetch. A bare header is never a trust source; only a token that
9
+ * survives verification produces a user.
10
+ */
11
+ import { importSPKI, jwtVerify, decodeProtectedHeader, } from "jose";
12
+ import { APP_ID_ENV, DEV_ENV, IDENTITY_ALG, IDENTITY_DEV_KEY_ID, IDENTITY_HEADER, IDENTITY_KEY_ID, ISSUER_ENV, PUBLIC_HEADER, PUBLIC_KEYS_ENV, PUBLIC_MARKER_SUB, assertPublicMarkerClaims, identityClaimsToEveryAppUser, ProtocolClaimsError, } from "./protocol.js";
13
+ export { APP_ID_ENV, DEV_ENV, IDENTITY_ALG, IDENTITY_DEV_KEY_ID, IDENTITY_HEADER, IDENTITY_KEY_ID, ISSUER_ENV, PUBLIC_HEADER, PUBLIC_KEYS_ENV, PUBLIC_MARKER_SUB, };
14
+ export class IdentityError extends Error {
15
+ status = 401;
16
+ constructor(message) {
17
+ super(message);
18
+ this.name = "IdentityError";
19
+ }
20
+ }
21
+ export class ConfigurationError extends Error {
22
+ status = 500;
23
+ constructor(message) {
24
+ super(message);
25
+ this.name = "ConfigurationError";
26
+ }
27
+ }
28
+ /**
29
+ * Parse the public key set from an env var value. Accepts a JSON array of PEM
30
+ * strings, or a single PEM string. Returns at least one key or throws.
31
+ */
32
+ export function parsePublicKeys(envValue) {
33
+ if (!envValue || envValue.trim().length === 0) {
34
+ throw new ConfigurationError(`${PUBLIC_KEYS_ENV} is not set — the gateway must inject the identity public key set.`);
35
+ }
36
+ const trimmed = envValue.trim();
37
+ let keys;
38
+ if (trimmed.startsWith("[")) {
39
+ let parsed;
40
+ try {
41
+ parsed = JSON.parse(trimmed);
42
+ }
43
+ catch (error) {
44
+ throw new ConfigurationError(`${PUBLIC_KEYS_ENV} must be a JSON array of PEM strings: ${error.message}`);
45
+ }
46
+ if (!Array.isArray(parsed) || parsed.some((k) => typeof k !== "string")) {
47
+ throw new ConfigurationError(`${PUBLIC_KEYS_ENV} must be a JSON array of PEM strings.`);
48
+ }
49
+ keys = parsed.map((k) => k.replace(/\\n/g, "\n"));
50
+ }
51
+ else {
52
+ keys = [trimmed.replace(/\\n/g, "\n")];
53
+ }
54
+ if (keys.length === 0) {
55
+ throw new ConfigurationError(`${PUBLIC_KEYS_ENV} contained no keys.`);
56
+ }
57
+ return keys;
58
+ }
59
+ const keyCache = new Map();
60
+ function importKey(pem) {
61
+ let cached = keyCache.get(pem);
62
+ if (!cached) {
63
+ cached = importSPKI(pem, IDENTITY_ALG);
64
+ keyCache.set(pem, cached);
65
+ }
66
+ return cached;
67
+ }
68
+ /**
69
+ * Verify an identity JWT fail-closed. Throws {@link IdentityError} on any
70
+ * problem (bad alg/kid, `none`, wrong key, expired, wrong audience, missing
71
+ * claims).
72
+ */
73
+ export async function verifyIdentityJwt(token, options) {
74
+ const payload = await verifyPinnedJwt(token, options, "user");
75
+ try {
76
+ return identityClaimsToEveryAppUser(payload);
77
+ }
78
+ catch (error) {
79
+ if (error instanceof ProtocolClaimsError) {
80
+ throw new IdentityError(error.message);
81
+ }
82
+ throw error;
83
+ }
84
+ }
85
+ /**
86
+ * The shared fail-closed verification core: pinned alg/kid, `none` rejected,
87
+ * `aud` checked, multi-key (current + next). Returns the verified payload.
88
+ */
89
+ async function verifyPinnedJwt(token, options, expectedTyp) {
90
+ if (!token)
91
+ throw new IdentityError("no identity token");
92
+ // Pin the header BEFORE attempting any signature work. This is what defeats
93
+ // `alg: none` and algorithm-confusion (e.g. an HS256 token forged with the
94
+ // public key as the HMAC secret).
95
+ let header;
96
+ try {
97
+ header = decodeProtectedHeader(token);
98
+ }
99
+ catch {
100
+ throw new IdentityError("malformed identity token");
101
+ }
102
+ if (header.alg !== IDENTITY_ALG) {
103
+ throw new IdentityError(`unexpected alg "${header.alg}" (expected ${IDENTITY_ALG})`);
104
+ }
105
+ const allowedKids = options.allowDevIdentities
106
+ ? [IDENTITY_KEY_ID, IDENTITY_DEV_KEY_ID]
107
+ : [IDENTITY_KEY_ID];
108
+ if (!header.kid || !allowedKids.includes(header.kid)) {
109
+ throw new IdentityError(`unexpected kid "${header.kid}"`);
110
+ }
111
+ if (expectedTyp === "user" && !options.issuer) {
112
+ throw new IdentityError(`${ISSUER_ENV} not configured — deploy with the Every App CLI or provide an explicit issuer.`);
113
+ }
114
+ const verifyOpts = {
115
+ algorithms: [IDENTITY_ALG],
116
+ audience: options.audience,
117
+ requiredClaims: ["exp"],
118
+ ...(options.issuer ? { issuer: options.issuer } : {}),
119
+ ...(options.now ? { currentDate: new Date(options.now) } : {}),
120
+ };
121
+ let lastErr;
122
+ for (const pem of options.publicKeys) {
123
+ try {
124
+ const key = await importKey(pem);
125
+ const { payload } = await jwtVerify(token, key, verifyOpts);
126
+ if (payload.typ !== expectedTyp) {
127
+ throw new IdentityError(`unexpected token typ "${payload.typ}" (expected ${expectedTyp})`);
128
+ }
129
+ return payload;
130
+ }
131
+ catch (err) {
132
+ lastErr = err;
133
+ }
134
+ }
135
+ throw new IdentityError(`identity verification failed: ${lastErr?.message ?? "no matching key"}`);
136
+ }
137
+ /**
138
+ * Verify a public-route marker (the value of `x-everyapp-public`). The marker
139
+ * is a gateway-signed, app-scoped JWT with `pub: true` and `typ: "public"` —
140
+ * a bare header is NEVER a trust source, so a re-exposed app worker cannot be
141
+ * flipped into public mode by anyone who can type a header. Throws on any
142
+ * problem.
143
+ */
144
+ export async function verifyPublicMarkerJwt(token, options) {
145
+ const payload = await verifyPinnedJwt(token, options, "public");
146
+ try {
147
+ assertPublicMarkerClaims(payload);
148
+ }
149
+ catch (error) {
150
+ if (error instanceof ProtocolClaimsError) {
151
+ throw new IdentityError(error.message);
152
+ }
153
+ throw error;
154
+ }
155
+ }
156
+ /**
157
+ * Resolve identity for an incoming proxied request. Public routes carry a
158
+ * gateway-SIGNED marker in `x-everyapp-public` and resolve to
159
+ * `{ user: null, isPublic: true }` only after the marker verifies. Everything
160
+ * else requires a valid identity JWT. Throws {@link IdentityError} on any
161
+ * problem — including a bare/forged public header — so a re-exposed worker
162
+ * fails closed.
163
+ */
164
+ export async function getIdentityFromRequest(request, options) {
165
+ const publicKeys = options.publicKeys ??
166
+ parsePublicKeys(options.env?.[options.keysEnvVar ?? PUBLIC_KEYS_ENV] ?? null);
167
+ // Dev identities are accepted only when the worker env opts in (everyapp dev
168
+ // sets EVERYAPP_DEV in .dev.vars). Production never sets it.
169
+ const devEnv = options.env?.[DEV_ENV];
170
+ const allowDevIdentities = options.allowDevIdentities ??
171
+ (typeof devEnv === "string" &&
172
+ (devEnv === "1" || devEnv.toLowerCase() === "true"));
173
+ const verifyOptions = {
174
+ publicKeys,
175
+ audience: options.audience,
176
+ issuer: options.issuer ??
177
+ (options.env?.[ISSUER_ENV] || undefined),
178
+ allowDevIdentities,
179
+ now: options.now,
180
+ };
181
+ const publicMarker = request.headers.get(PUBLIC_HEADER);
182
+ if (publicMarker) {
183
+ await verifyPublicMarkerJwt(publicMarker, verifyOptions);
184
+ return { user: null, isPublic: true };
185
+ }
186
+ const token = request.headers.get(IDENTITY_HEADER);
187
+ if (!token) {
188
+ throw new IdentityError("request reached the app without an identity token (not proxied through the gateway?)");
189
+ }
190
+ const user = await verifyIdentityJwt(token, verifyOptions);
191
+ return { user, isPublic: false };
192
+ }
@@ -0,0 +1,3 @@
1
+ export * from "./protocol.js";
2
+ export { ConfigurationError, IdentityError, getIdentityFromRequest, parsePublicKeys, verifyIdentityJwt, verifyPublicMarkerJwt, type IdentityResult, type RequestIdentityOptions, type VerifyOptions, } from "./identity.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/internal/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,sBAAsB,EACtB,eAAe,EACf,iBAAiB,EACjB,qBAAqB,EACrB,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAC3B,KAAK,aAAa,GACnB,MAAM,eAAe,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from "./protocol.js";
2
+ export { ConfigurationError, IdentityError, getIdentityFromRequest, parsePublicKeys, verifyIdentityJwt, verifyPublicMarkerJwt, } from "./identity.js";
@@ -0,0 +1,111 @@
1
+ /**
2
+ * @every-app/sdk/internal — Every App platform protocol internals.
3
+ *
4
+ * This subpath is for the Every App platform itself (gateway, perimeter, CLI),
5
+ * not for app authors. It owns the wire constants, claim shapes, claim codecs,
6
+ * and gateway-side JWT minters shared by the platform packages.
7
+ */
8
+ import { type JWTPayload } from "jose";
9
+ export declare const IDENTITY_ALG = "RS256";
10
+ export declare const IDENTITY_KEY_ID = "everyapp-identity";
11
+ export declare const IDENTITY_DEV_KEY_ID = "everyapp-identity-dev";
12
+ export declare const IDENTITY_HEADER = "x-everyapp-identity";
13
+ export declare const PUBLIC_HEADER = "x-everyapp-public";
14
+ /** 120-second lifetime — caps revocation staleness while surviving clock skew. */
15
+ export declare const IDENTITY_TTL_SECONDS = 120;
16
+ /** Env var carrying the app id used as the expected identity audience. */
17
+ export declare const APP_ID_ENV = "EVERYAPP_APP_ID";
18
+ /** Default env var carrying a JSON array of SPKI PEM public keys. */
19
+ export declare const PUBLIC_KEYS_ENV = "EVERYAPP_IDENTITY_PUBLIC_KEYS";
20
+ /** Env var carrying the expected gateway issuer for user identity verification. */
21
+ export declare const ISSUER_ENV = "EVERYAPP_IDENTITY_ISSUER";
22
+ /** When set to `1` or `true` in the worker env, the dev identity kid is accepted. */
23
+ export declare const DEV_ENV = "EVERYAPP_DEV";
24
+ /** `sub` claim the gateway mints public-route markers with. */
25
+ export declare const PUBLIC_MARKER_SUB = "public";
26
+ export type IdentityChannel = "web" | "api" | "mcp" | "agent";
27
+ export type IdentityTokenType = "user" | "public";
28
+ /** The actor on whose behalf the request is made (user, MCP client, agent). */
29
+ export interface IdentityActor {
30
+ sub: string;
31
+ }
32
+ export interface IdentitySubject {
33
+ sub: string;
34
+ email: string;
35
+ orgId: string;
36
+ orgRole: string;
37
+ }
38
+ export interface EveryAppUser {
39
+ /** User id (the `sub` claim). */
40
+ id: string;
41
+ email: string;
42
+ orgId: string;
43
+ orgRole: string;
44
+ channel: IdentityChannel;
45
+ /** The acting principal (user, or `mcp:<client>` / agent). */
46
+ actor: IdentityActor;
47
+ scopes: string[];
48
+ jti: string;
49
+ }
50
+ export interface IdentityClaims extends JWTPayload {
51
+ typ: "user";
52
+ email: string;
53
+ org_id: string;
54
+ org_role: string;
55
+ chan: IdentityChannel;
56
+ act: IdentityActor;
57
+ scopes: string[];
58
+ jti: string;
59
+ }
60
+ export interface PublicMarkerClaims extends JWTPayload {
61
+ typ: "public";
62
+ pub: true;
63
+ jti: string;
64
+ }
65
+ export declare class ProtocolClaimsError extends Error {
66
+ constructor(message: string);
67
+ }
68
+ export declare function identitySubjectToClaims(subject: IdentitySubject, opts: {
69
+ channel?: IdentityChannel;
70
+ actor?: IdentityActor;
71
+ scopes?: string[];
72
+ jti: string;
73
+ }): IdentityClaims;
74
+ export declare function identityClaimsToEveryAppUser(payload: JWTPayload): EveryAppUser;
75
+ export declare function publicMarkerClaims(jti: string): PublicMarkerClaims;
76
+ export declare function assertPublicMarkerClaims(payload: JWTPayload): void;
77
+ export interface MintIdentityOptions {
78
+ subject: IdentitySubject;
79
+ /** The app id this token is scoped to — becomes the `aud` claim. */
80
+ audience: string;
81
+ issuer: string;
82
+ channel?: IdentityChannel;
83
+ actor?: IdentityActor;
84
+ scopes?: string[];
85
+ ttlSeconds?: number;
86
+ now?: number;
87
+ /** Header kid. Defaults to the production kid; dev mints with the dev kid. */
88
+ keyId?: string;
89
+ }
90
+ /**
91
+ * Mint an identity JWT. Returns the compact JWS string to inject as
92
+ * `x-everyapp-identity`.
93
+ */
94
+ export declare function mintIdentityJwt(privateKeyPem: string, opts: MintIdentityOptions): Promise<string>;
95
+ export interface MintPublicMarkerOptions {
96
+ /** The app id this marker is scoped to — becomes the `aud` claim. */
97
+ audience: string;
98
+ issuer: string;
99
+ ttlSeconds?: number;
100
+ now?: number;
101
+ /** Header kid. Defaults to the production kid; dev mints with the dev kid. */
102
+ keyId?: string;
103
+ }
104
+ /**
105
+ * Mint the public-route marker for `x-everyapp-public`. A bare header value
106
+ * is never a trust source, so the marker is a signed, short-lived, app-scoped
107
+ * JWT with `pub: true` and `typ: "public"` that the SDK verifies exactly like
108
+ * an identity token.
109
+ */
110
+ export declare function mintPublicMarkerJwt(privateKeyPem: string, opts: MintPublicMarkerOptions): Promise<string>;
111
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/internal/protocol.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,139 @@
1
+ /**
2
+ * @every-app/sdk/internal — Every App platform protocol internals.
3
+ *
4
+ * This subpath is for the Every App platform itself (gateway, perimeter, CLI),
5
+ * not for app authors. It owns the wire constants, claim shapes, claim codecs,
6
+ * and gateway-side JWT minters shared by the platform packages.
7
+ */
8
+ import { SignJWT, importPKCS8 } from "jose";
9
+ export const IDENTITY_ALG = "RS256";
10
+ export const IDENTITY_KEY_ID = "everyapp-identity";
11
+ export const IDENTITY_DEV_KEY_ID = "everyapp-identity-dev";
12
+ export const IDENTITY_HEADER = "x-everyapp-identity";
13
+ export const PUBLIC_HEADER = "x-everyapp-public";
14
+ /** 120-second lifetime — caps revocation staleness while surviving clock skew. */
15
+ export const IDENTITY_TTL_SECONDS = 120;
16
+ /** Env var carrying the app id used as the expected identity audience. */
17
+ export const APP_ID_ENV = "EVERYAPP_APP_ID";
18
+ /** Default env var carrying a JSON array of SPKI PEM public keys. */
19
+ export const PUBLIC_KEYS_ENV = "EVERYAPP_IDENTITY_PUBLIC_KEYS";
20
+ /** Env var carrying the expected gateway issuer for user identity verification. */
21
+ export const ISSUER_ENV = "EVERYAPP_IDENTITY_ISSUER";
22
+ /** When set to `1` or `true` in the worker env, the dev identity kid is accepted. */
23
+ export const DEV_ENV = "EVERYAPP_DEV";
24
+ /** `sub` claim the gateway mints public-route markers with. */
25
+ export const PUBLIC_MARKER_SUB = "public";
26
+ export class ProtocolClaimsError extends Error {
27
+ constructor(message) {
28
+ super(message);
29
+ this.name = "ProtocolClaimsError";
30
+ }
31
+ }
32
+ export function identitySubjectToClaims(subject, opts) {
33
+ return {
34
+ typ: "user",
35
+ email: subject.email,
36
+ org_id: subject.orgId,
37
+ org_role: subject.orgRole,
38
+ chan: opts.channel ?? "web",
39
+ act: opts.actor ?? { sub: subject.sub },
40
+ scopes: opts.scopes ?? ["*"],
41
+ jti: opts.jti,
42
+ };
43
+ }
44
+ export function identityClaimsToEveryAppUser(payload) {
45
+ if (payload.typ !== "user") {
46
+ throw new ProtocolClaimsError("identity token has wrong typ");
47
+ }
48
+ const sub = payload.sub;
49
+ const email = payload.email;
50
+ const orgId = payload.org_id;
51
+ const orgRole = payload.org_role;
52
+ if (!sub || !email || !orgId || !orgRole) {
53
+ throw new ProtocolClaimsError("identity token missing required claims");
54
+ }
55
+ const chan = payload.chan ?? "web";
56
+ const act = payload.act ?? { sub };
57
+ const scopes = Array.isArray(payload.scopes)
58
+ ? payload.scopes.filter((scope) => typeof scope === "string")
59
+ : ["*"];
60
+ return {
61
+ id: sub,
62
+ email,
63
+ orgId,
64
+ orgRole,
65
+ channel: chan,
66
+ actor: { sub: act.sub ?? sub },
67
+ scopes,
68
+ jti: payload.jti ?? "",
69
+ };
70
+ }
71
+ export function publicMarkerClaims(jti) {
72
+ return { typ: "public", pub: true, jti };
73
+ }
74
+ export function assertPublicMarkerClaims(payload) {
75
+ if (payload.typ !== "public") {
76
+ throw new ProtocolClaimsError("public marker has wrong typ");
77
+ }
78
+ if (payload.pub !== true || payload.sub !== PUBLIC_MARKER_SUB) {
79
+ throw new ProtocolClaimsError("token is not a public-route marker");
80
+ }
81
+ }
82
+ let cachedPrivateKey = null;
83
+ async function loadPrivateKey(privateKeyPem) {
84
+ const pem = privateKeyPem.replace(/\\n/g, "\n");
85
+ if (cachedPrivateKey && cachedPrivateKey.pem === pem) {
86
+ return cachedPrivateKey.key;
87
+ }
88
+ const key = await importPKCS8(pem, IDENTITY_ALG);
89
+ cachedPrivateKey = { pem, key };
90
+ return key;
91
+ }
92
+ /**
93
+ * Mint an identity JWT. Returns the compact JWS string to inject as
94
+ * `x-everyapp-identity`.
95
+ */
96
+ export async function mintIdentityJwt(privateKeyPem, opts) {
97
+ const key = await loadPrivateKey(privateKeyPem);
98
+ const nowSec = Math.floor((opts.now ?? Date.now()) / 1000);
99
+ const ttl = opts.ttlSeconds ?? IDENTITY_TTL_SECONDS;
100
+ const jti = crypto.randomUUID();
101
+ return new SignJWT(identitySubjectToClaims(opts.subject, {
102
+ channel: opts.channel,
103
+ actor: opts.actor,
104
+ scopes: opts.scopes,
105
+ jti,
106
+ }))
107
+ .setProtectedHeader({
108
+ alg: IDENTITY_ALG,
109
+ kid: opts.keyId ?? IDENTITY_KEY_ID,
110
+ })
111
+ .setIssuer(opts.issuer)
112
+ .setSubject(opts.subject.sub)
113
+ .setAudience(opts.audience)
114
+ .setIssuedAt(nowSec)
115
+ .setExpirationTime(nowSec + ttl)
116
+ .sign(key);
117
+ }
118
+ /**
119
+ * Mint the public-route marker for `x-everyapp-public`. A bare header value
120
+ * is never a trust source, so the marker is a signed, short-lived, app-scoped
121
+ * JWT with `pub: true` and `typ: "public"` that the SDK verifies exactly like
122
+ * an identity token.
123
+ */
124
+ export async function mintPublicMarkerJwt(privateKeyPem, opts) {
125
+ const key = await loadPrivateKey(privateKeyPem);
126
+ const nowSec = Math.floor((opts.now ?? Date.now()) / 1000);
127
+ const ttl = opts.ttlSeconds ?? IDENTITY_TTL_SECONDS;
128
+ return new SignJWT(publicMarkerClaims(crypto.randomUUID()))
129
+ .setProtectedHeader({
130
+ alg: IDENTITY_ALG,
131
+ kid: opts.keyId ?? IDENTITY_KEY_ID,
132
+ })
133
+ .setIssuer(opts.issuer)
134
+ .setSubject(PUBLIC_MARKER_SUB)
135
+ .setAudience(opts.audience)
136
+ .setIssuedAt(nowSec)
137
+ .setExpirationTime(nowSec + ttl)
138
+ .sign(key);
139
+ }
@@ -0,0 +1,55 @@
1
+ /**
2
+ * `everyApp()` — the app-side identity boundary.
3
+ *
4
+ * import manifest from "../everyapp.config.js";
5
+ * export default everyApp(handler, manifest);
6
+ *
7
+ * The wrapper verifies the gateway-injected identity before app code runs,
8
+ * stores the result on the original Request, and then delegates to the
9
+ * worker-style handler.
10
+ */
11
+ import { ConfigurationError, IdentityError, type EveryAppUser, type IdentityResult } from "../internal/index.js";
12
+ export { ConfigurationError, IdentityError };
13
+ export type { EveryAppUser, IdentityResult };
14
+ export interface ExecutionContextLike {
15
+ waitUntil(promise: Promise<unknown>): void;
16
+ passThroughOnException?(): void;
17
+ }
18
+ export interface EveryAppManifestLike {
19
+ id: string;
20
+ [key: string]: unknown;
21
+ }
22
+ export interface EveryAppOptions {
23
+ /** Optional expected issuer (gateway URL). Defaults to env.EVERYAPP_IDENTITY_ISSUER when set. */
24
+ issuer?: string;
25
+ /** Env var holding the public key set. Defaults to EVERYAPP_IDENTITY_PUBLIC_KEYS. */
26
+ keysEnvVar?: string;
27
+ /** Provide keys directly (tests / non-standard delivery). */
28
+ publicKeys?: string[];
29
+ /**
30
+ * Accept dev identity tokens. Defaults to reading EVERYAPP_DEV from env.
31
+ * Never enable this in production.
32
+ */
33
+ allowDevIdentities?: boolean;
34
+ /** Override for tests. */
35
+ now?: number;
36
+ }
37
+ /** The handler accepted by everyApp, with the verified user as a 4th argument. */
38
+ export type EveryAppHandler<TEnv = Record<string, unknown>> = (request: Request, env: TEnv, ctx: ExecutionContextLike, user: EveryAppUser | null) => Response | Promise<Response>;
39
+ interface EveryAppExport<TEnv> {
40
+ fetch(request: Request, env: TEnv, ctx: ExecutionContextLike): Promise<Response>;
41
+ }
42
+ /**
43
+ * Return the verified Every App user for this request, or null for a declared
44
+ * public request. Uses the request cache first, then verifies the identity
45
+ * headers from the app id and public keys configured in env.
46
+ */
47
+ export declare function getEveryAppUser(request: Request, env: object): Promise<EveryAppUser | null>;
48
+ /**
49
+ * Return the verified user, or throw the same 401 JSON Response shape as
50
+ * everyApp() when the request is public or unauthenticated.
51
+ */
52
+ export declare function requireEveryAppUser(request: Request, env: object): Promise<EveryAppUser>;
53
+ export declare function hasScope(user: EveryAppUser, scope: string): boolean;
54
+ export declare function everyApp<TEnv = Record<string, unknown>>(handler: EveryAppHandler<TEnv>, manifest: EveryAppManifestLike, options?: EveryAppOptions): EveryAppExport<TEnv>;
55
+ //# sourceMappingURL=everyApp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"everyApp.d.ts","sourceRoot":"","sources":["../../src/server/everyApp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAEL,kBAAkB,EAElB,aAAa,EAIb,KAAK,YAAY,EACjB,KAAK,cAAc,EACpB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,CAAC;AAC7C,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,CAAC;AAE7C,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IAC3C,sBAAsB,CAAC,IAAI,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,iGAAiG;IACjG,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qFAAqF;IACrF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,0BAA0B;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,kFAAkF;AAClF,MAAM,MAAM,eAAe,CAAC,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAC5D,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,IAAI,EACT,GAAG,EAAE,oBAAoB,EACzB,IAAI,EAAE,YAAY,GAAG,IAAI,KACtB,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;AAElC,UAAU,cAAc,CAAC,IAAI;IAC3B,KAAK,CACH,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,IAAI,EACT,GAAG,EAAE,oBAAoB,GACxB,OAAO,CAAC,QAAQ,CAAC,CAAC;CACtB;AAiFD;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAW9B;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,YAAY,CAAC,CAevB;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAEnE;AAED,wBAAgB,QAAQ,CAAC,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACrD,OAAO,EAAE,eAAe,CAAC,IAAI,CAAC,EAC9B,QAAQ,EAAE,oBAAoB,EAC9B,OAAO,GAAE,eAAoB,GAC5B,cAAc,CAAC,IAAI,CAAC,CAqBtB"}