@run402/functions 3.14.1 → 4.0.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.
- package/dist/config.d.ts +0 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +0 -1
- package/dist/config.js.map +1 -1
- package/dist/lib/project-jwt-keys.d.ts +20 -13
- package/dist/lib/project-jwt-keys.d.ts.map +1 -1
- package/dist/lib/project-jwt-keys.js +21 -31
- package/dist/lib/project-jwt-keys.js.map +1 -1
- package/package.json +1 -1
package/dist/config.d.ts
CHANGED
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,MAAM
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,MAAM;;;;;CAKlB,CAAC"}
|
package/dist/config.js
CHANGED
|
@@ -6,6 +6,5 @@ export const config = {
|
|
|
6
6
|
get PROJECT_ID() { return process.env.RUN402_PROJECT_ID || ""; },
|
|
7
7
|
get SERVICE_KEY() { return process.env.RUN402_SERVICE_KEY || ""; },
|
|
8
8
|
get ANON_KEY() { return process.env.RUN402_ANON_KEY || ""; },
|
|
9
|
-
get JWT_SECRET() { return process.env.RUN402_JWT_SECRET || ""; },
|
|
10
9
|
};
|
|
11
10
|
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,0DAA0D;AAC1D,gEAAgE;AAChE,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,IAAI,QAAQ,KAAK,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,wBAAwB,CAAC,CAAC,CAAC;IAClF,IAAI,UAAU,KAAK,OAAO,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC,CAAC;IAChE,IAAI,WAAW,KAAK,OAAO,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC,CAAC;IAClE,IAAI,QAAQ,KAAK,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,0DAA0D;AAC1D,gEAAgE;AAChE,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,IAAI,QAAQ,KAAK,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,wBAAwB,CAAC,CAAC,CAAC;IAClF,IAAI,UAAU,KAAK,OAAO,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC,CAAC;IAChE,IAAI,WAAW,KAAK,OAAO,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC,CAAC;IAClE,IAAI,QAAQ,KAAK,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC,CAAC;CAC7D,CAAC"}
|
|
@@ -17,23 +17,30 @@
|
|
|
17
17
|
* pattern for the actor-context key — same lazy single-flight fetch, same
|
|
18
18
|
* service-key auth, same "failures are non-fatal, the next request retries".
|
|
19
19
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
20
|
+
* FETCH-ONLY. There was a transition fallback here: while `RUN402_JWT_SECRET`
|
|
21
|
+
* was still injected, it was kept as a second, kid-less verification key tried
|
|
22
|
+
* after the fetched keyset. It was load-bearing for exactly one window — after
|
|
23
|
+
* the fleet carried this runtime but BEFORE the gateway's signing key became
|
|
24
|
+
* asymmetric, the gateway was still minting HS256 tokens that an
|
|
25
|
+
* asymmetric-only keyset cannot verify.
|
|
26
|
+
*
|
|
27
|
+
* That window closed. The gateway signs ES256 (`kid=p1-2026-08`), and §8 both
|
|
28
|
+
* stopped injecting the env key and swept it out of the fleet, so the fallback
|
|
29
|
+
* had already stopped firing in production before this removed it — it read an
|
|
30
|
+
* env var that is no longer set on any live function.
|
|
31
|
+
*
|
|
32
|
+
* The consequence is deliberate and is the whole point: with no fallback, a
|
|
33
|
+
* failed keyset fetch leaves NO keys, and `getUser()` fails closed rather than
|
|
34
|
+
* silently falling back to material the tenant's own environment could supply.
|
|
27
35
|
* See `openspec/changes/functions-runtime-key-decoupling/design.md`.
|
|
28
36
|
*/
|
|
29
37
|
import type { VerificationKey } from "./jwt.js";
|
|
30
38
|
/**
|
|
31
|
-
* The keys `getUser()` should verify against
|
|
39
|
+
* The keys `getUser()` should verify against.
|
|
32
40
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* selects on `kid` and refuses to fall back on a signature mismatch.
|
|
41
|
+
* The fetched public keyset, and nothing else. An empty array is a legitimate
|
|
42
|
+
* result — it means the fetch has not succeeded yet — and callers must treat it
|
|
43
|
+
* as "cannot verify", never as "no verification needed".
|
|
37
44
|
*/
|
|
38
45
|
export declare function projectJwtVerificationKeys(): VerificationKey[];
|
|
39
46
|
/**
|
|
@@ -42,7 +49,7 @@ export declare function projectJwtVerificationKeys(): VerificationKey[];
|
|
|
42
49
|
* Single-flight: concurrent invocations in the same execution environment
|
|
43
50
|
* share one fetch. Cached for the life of the environment, so a warm Lambda
|
|
44
51
|
* pays nothing. Never throws — a failed fetch leaves whatever keys are
|
|
45
|
-
* available (possibly
|
|
52
|
+
* available (possibly none at all) and the next request retries.
|
|
46
53
|
*/
|
|
47
54
|
export declare function ensureProjectJwtKeysLoaded(): Promise<void>;
|
|
48
55
|
/** True when verification has no key at all — the caller must fail CLOSED
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-jwt-keys.d.ts","sourceRoot":"","sources":["../../src/lib/project-jwt-keys.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"project-jwt-keys.d.ts","sourceRoot":"","sources":["../../src/lib/project-jwt-keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAchD;;;;;;GAMG;AACH,wBAAgB,0BAA0B,IAAI,eAAe,EAAE,CAE9D;AAED;;;;;;;GAOG;AACH,wBAAsB,0BAA0B,IAAI,OAAO,CAAC,IAAI,CAAC,CAehE;AAED;2DAC2D;AAC3D,wBAAgB,yBAAyB,IAAI,OAAO,CAEnD;AAsCD,uDAAuD;AACvD,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,eAAe,EAAE,GAAG,IAAI,GAAG,IAAI,CAG9E;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,6BAA6B,yBAAyB,CAAC;AAQpE,2DAA2D;AAC3D,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAS7E;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAGhF"}
|
|
@@ -17,45 +17,35 @@
|
|
|
17
17
|
* pattern for the actor-context key — same lazy single-flight fetch, same
|
|
18
18
|
* service-key auth, same "failures are non-fatal, the next request retries".
|
|
19
19
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
20
|
+
* FETCH-ONLY. There was a transition fallback here: while `RUN402_JWT_SECRET`
|
|
21
|
+
* was still injected, it was kept as a second, kid-less verification key tried
|
|
22
|
+
* after the fetched keyset. It was load-bearing for exactly one window — after
|
|
23
|
+
* the fleet carried this runtime but BEFORE the gateway's signing key became
|
|
24
|
+
* asymmetric, the gateway was still minting HS256 tokens that an
|
|
25
|
+
* asymmetric-only keyset cannot verify.
|
|
26
|
+
*
|
|
27
|
+
* That window closed. The gateway signs ES256 (`kid=p1-2026-08`), and §8 both
|
|
28
|
+
* stopped injecting the env key and swept it out of the fleet, so the fallback
|
|
29
|
+
* had already stopped firing in production before this removed it — it read an
|
|
30
|
+
* env var that is no longer set on any live function.
|
|
31
|
+
*
|
|
32
|
+
* The consequence is deliberate and is the whole point: with no fallback, a
|
|
33
|
+
* failed keyset fetch leaves NO keys, and `getUser()` fails closed rather than
|
|
34
|
+
* silently falling back to material the tenant's own environment could supply.
|
|
27
35
|
* See `openspec/changes/functions-runtime-key-decoupling/design.md`.
|
|
28
36
|
*/
|
|
29
37
|
import { createPublicKey } from "node:crypto";
|
|
30
38
|
let cached = null;
|
|
31
39
|
let fetchInFlight = null;
|
|
32
40
|
/**
|
|
33
|
-
* The keys `getUser()` should verify against
|
|
41
|
+
* The keys `getUser()` should verify against.
|
|
34
42
|
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* selects on `kid` and refuses to fall back on a signature mismatch.
|
|
43
|
+
* The fetched public keyset, and nothing else. An empty array is a legitimate
|
|
44
|
+
* result — it means the fetch has not succeeded yet — and callers must treat it
|
|
45
|
+
* as "cannot verify", never as "no verification needed".
|
|
39
46
|
*/
|
|
40
47
|
export function projectJwtVerificationKeys() {
|
|
41
|
-
|
|
42
|
-
const legacy = legacyEnvKey();
|
|
43
|
-
if (legacy)
|
|
44
|
-
keys.push(legacy);
|
|
45
|
-
return keys;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* The env-injected key, as a kid-less LEGACY verification key.
|
|
49
|
-
*
|
|
50
|
-
* `legacy: true` is what lets it verify the kid-less tokens the gateway signs
|
|
51
|
-
* today; once the gateway signs with a `kid`, its tokens select the fetched
|
|
52
|
-
* key by id and never reach this one.
|
|
53
|
-
*/
|
|
54
|
-
function legacyEnvKey() {
|
|
55
|
-
const raw = process.env.RUN402_JWT_SECRET;
|
|
56
|
-
if (!raw)
|
|
57
|
-
return null;
|
|
58
|
-
return { key: Buffer.from(raw, "utf8"), alg: "HS256", legacy: true };
|
|
48
|
+
return cached ? [...cached] : [];
|
|
59
49
|
}
|
|
60
50
|
/**
|
|
61
51
|
* Ensure the keyset is loaded before a synchronous verify.
|
|
@@ -63,7 +53,7 @@ function legacyEnvKey() {
|
|
|
63
53
|
* Single-flight: concurrent invocations in the same execution environment
|
|
64
54
|
* share one fetch. Cached for the life of the environment, so a warm Lambda
|
|
65
55
|
* pays nothing. Never throws — a failed fetch leaves whatever keys are
|
|
66
|
-
* available (possibly
|
|
56
|
+
* available (possibly none at all) and the next request retries.
|
|
67
57
|
*/
|
|
68
58
|
export async function ensureProjectJwtKeysLoaded() {
|
|
69
59
|
if (cached && cached.length > 0)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-jwt-keys.js","sourceRoot":"","sources":["../../src/lib/project-jwt-keys.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"project-jwt-keys.js","sourceRoot":"","sources":["../../src/lib/project-jwt-keys.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@run402/functions",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"description": "In-function helper library for Run402 serverless functions - db, adminDb, getUser, email, ai, assets, verifyWebhook. Auto-bundled into deployed functions; also installable for local TypeScript autocomplete.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|