@de-otio/trellis 0.12.2 → 0.12.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"pre-token-generation.d.ts","sourceRoot":"","sources":["../../src/lambda/pre-token-generation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAEV,kCAAkC,EACnC,MAAM,YAAY,CAAC;AAwJpB,eAAO,MAAM,OAAO,EAAE,kCAyHrB,CAAC"}
1
+ {"version":3,"file":"pre-token-generation.d.ts","sourceRoot":"","sources":["../../src/lambda/pre-token-generation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAEV,kCAAkC,EACnC,MAAM,YAAY,CAAC;AAsKpB,eAAO,MAAM,OAAO,EAAE,kCAoKrB,CAAC"}
@@ -37,6 +37,17 @@ const DRIFT_CLAIMS = {
37
37
  tenantRole: "",
38
38
  handle: "",
39
39
  };
40
+ // Read-after-write retry budget for the RDS fallback. On a brand-new signup,
41
+ // the first token can be minted before PostConfirmation's provisioning
42
+ // transaction is visible; a single miss would emit the drift sentinel (empty
43
+ // `custom:userId`) and break every downstream `where:{id}` lookup until the
44
+ // user re-auths. We retry the load a bounded number of times so the write can
45
+ // land. Genuine drift (post-RDS-restore) simply exhausts the budget and falls
46
+ // through to the sentinel exactly as before. Runtime config, not compiled-in
47
+ // constants (threshold-secrecy rule).
48
+ const DEFAULT_RDS_RETRY_MAX = 4;
49
+ const DEFAULT_RDS_RETRY_DELAY_MS = 150;
50
+ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
40
51
  function parseIdpGroups(raw) {
41
52
  if (!raw)
42
53
  return [];
@@ -138,6 +149,15 @@ export const handler = async (event) => {
138
149
  // Without invalidation, suspended users keep valid claims for up to one
139
150
  // cache TTL (DEFAULT_CACHE_TTL_SECONDS = 3600s). Tracked as G2 finding H3.
140
151
  let claims = await claimsCache.get(cognitoSub);
152
+ // A cached entry with an empty userId is never legitimate: a real user's
153
+ // claims always carry the cuid, and the drift sentinel is never written to
154
+ // the cache (both `put` sites guard on a truthy userId). Treat such an entry
155
+ // as a miss so the RDS fallback can recover the real userId rather than
156
+ // serving a token with an empty `custom:userId`.
157
+ if (claims && !claims.userId) {
158
+ logger.warn("pretoken.empty_cache_entry", { cognitoSub });
159
+ claims = null;
160
+ }
141
161
  let cacheHit = !!claims;
142
162
  if (!claims) {
143
163
  // RDS is consulted only on a genuine cache miss. Emit a filterable event so
@@ -158,9 +178,33 @@ export const handler = async (event) => {
158
178
  error: err?.code ?? "unknown",
159
179
  });
160
180
  }
161
- const loaded = await withLambdaDbBreaker(() => loadFromRds(db, cognitoSub, federated, preferredTenantId), "pretoken.load_from_rds");
181
+ // Bounded read-after-write retry: re-read until the user row is visible or
182
+ // the budget is spent (see DEFAULT_RDS_RETRY_* above). Each attempt is wrapped
183
+ // in the breaker, so a saturated DB still fast-fails (the breaker throws and
184
+ // issuance fails) rather than being retried into an exhausted instance — a
185
+ // null return is a successful read, not a breaker failure, so retrying it is
186
+ // safe.
187
+ const retryMax = Math.max(1, Number(process.env.PRETOKEN_RDS_RETRY_MAX ?? DEFAULT_RDS_RETRY_MAX));
188
+ const retryDelayMs = Math.max(0, Number(process.env.PRETOKEN_RDS_RETRY_DELAY_MS ?? DEFAULT_RDS_RETRY_DELAY_MS));
189
+ let loaded = await withLambdaDbBreaker(() => loadFromRds(db, cognitoSub, federated, preferredTenantId), "pretoken.load_from_rds");
190
+ let rdsAttempts = 1;
191
+ while (!loaded.user && rdsAttempts < retryMax) {
192
+ await sleep(retryDelayMs);
193
+ loaded = await withLambdaDbBreaker(() => loadFromRds(db, cognitoSub, federated, preferredTenantId), "pretoken.load_from_rds");
194
+ rdsAttempts++;
195
+ }
196
+ if (rdsAttempts > 1) {
197
+ // Fires only when the race actually occurred — a low-noise signal that
198
+ // distinguishes the read-after-write window from steady state, and shows
199
+ // whether the retry recovered the row.
200
+ logger.warn("pretoken.rds_retry", {
201
+ cognitoSub,
202
+ rdsAttempts,
203
+ recovered: !!loaded.user,
204
+ });
205
+ }
162
206
  if (!loaded.user) {
163
- logger.warn("pretoken.drift", { cognitoSub });
207
+ logger.warn("pretoken.drift", { cognitoSub, rdsAttempts });
164
208
  claims = { ...DRIFT_CLAIMS };
165
209
  writeTokenClaims(event, claims);
166
210
  return event;
@@ -1 +1 @@
1
- {"version":3,"file":"pre-token-generation.js","sourceRoot":"","sources":["../../src/lambda/pre-token-generation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pre-token-generation.js","sourceRoot":"","sources":["../../src/lambda/pre-token-generation.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@de-otio/trellis",
3
- "version": "0.12.2",
3
+ "version": "0.12.3",
4
4
  "license": "AGPL-3.0-or-later",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -51,6 +51,20 @@ const DRIFT_CLAIMS: CachedClaims = {
51
51
  handle: "",
52
52
  };
53
53
 
54
+ // Read-after-write retry budget for the RDS fallback. On a brand-new signup,
55
+ // the first token can be minted before PostConfirmation's provisioning
56
+ // transaction is visible; a single miss would emit the drift sentinel (empty
57
+ // `custom:userId`) and break every downstream `where:{id}` lookup until the
58
+ // user re-auths. We retry the load a bounded number of times so the write can
59
+ // land. Genuine drift (post-RDS-restore) simply exhausts the budget and falls
60
+ // through to the sentinel exactly as before. Runtime config, not compiled-in
61
+ // constants (threshold-secrecy rule).
62
+ const DEFAULT_RDS_RETRY_MAX = 4;
63
+ const DEFAULT_RDS_RETRY_DELAY_MS = 150;
64
+
65
+ const sleep = (ms: number): Promise<void> =>
66
+ new Promise((resolve) => setTimeout(resolve, ms));
67
+
54
68
  function parseIdpGroups(raw: string | undefined | null): string[] {
55
69
  if (!raw) return [];
56
70
  return raw
@@ -191,6 +205,15 @@ export const handler: PreTokenGenerationV2TriggerHandler = async (event) => {
191
205
  // Without invalidation, suspended users keep valid claims for up to one
192
206
  // cache TTL (DEFAULT_CACHE_TTL_SECONDS = 3600s). Tracked as G2 finding H3.
193
207
  let claims = await claimsCache.get(cognitoSub);
208
+ // A cached entry with an empty userId is never legitimate: a real user's
209
+ // claims always carry the cuid, and the drift sentinel is never written to
210
+ // the cache (both `put` sites guard on a truthy userId). Treat such an entry
211
+ // as a miss so the RDS fallback can recover the real userId rather than
212
+ // serving a token with an empty `custom:userId`.
213
+ if (claims && !claims.userId) {
214
+ logger.warn("pretoken.empty_cache_entry", { cognitoSub });
215
+ claims = null;
216
+ }
194
217
  let cacheHit = !!claims;
195
218
 
196
219
  if (!claims) {
@@ -211,13 +234,47 @@ export const handler: PreTokenGenerationV2TriggerHandler = async (event) => {
211
234
  error: (err as { code?: string })?.code ?? "unknown",
212
235
  });
213
236
  }
214
- const loaded = await withLambdaDbBreaker(
237
+
238
+ // Bounded read-after-write retry: re-read until the user row is visible or
239
+ // the budget is spent (see DEFAULT_RDS_RETRY_* above). Each attempt is wrapped
240
+ // in the breaker, so a saturated DB still fast-fails (the breaker throws and
241
+ // issuance fails) rather than being retried into an exhausted instance — a
242
+ // null return is a successful read, not a breaker failure, so retrying it is
243
+ // safe.
244
+ const retryMax = Math.max(
245
+ 1,
246
+ Number(process.env.PRETOKEN_RDS_RETRY_MAX ?? DEFAULT_RDS_RETRY_MAX),
247
+ );
248
+ const retryDelayMs = Math.max(
249
+ 0,
250
+ Number(process.env.PRETOKEN_RDS_RETRY_DELAY_MS ?? DEFAULT_RDS_RETRY_DELAY_MS),
251
+ );
252
+ let loaded = await withLambdaDbBreaker(
215
253
  () => loadFromRds(db, cognitoSub, federated, preferredTenantId),
216
254
  "pretoken.load_from_rds",
217
255
  );
256
+ let rdsAttempts = 1;
257
+ while (!loaded.user && rdsAttempts < retryMax) {
258
+ await sleep(retryDelayMs);
259
+ loaded = await withLambdaDbBreaker(
260
+ () => loadFromRds(db, cognitoSub, federated, preferredTenantId),
261
+ "pretoken.load_from_rds",
262
+ );
263
+ rdsAttempts++;
264
+ }
265
+ if (rdsAttempts > 1) {
266
+ // Fires only when the race actually occurred — a low-noise signal that
267
+ // distinguishes the read-after-write window from steady state, and shows
268
+ // whether the retry recovered the row.
269
+ logger.warn("pretoken.rds_retry", {
270
+ cognitoSub,
271
+ rdsAttempts,
272
+ recovered: !!loaded.user,
273
+ });
274
+ }
218
275
 
219
276
  if (!loaded.user) {
220
- logger.warn("pretoken.drift", { cognitoSub });
277
+ logger.warn("pretoken.drift", { cognitoSub, rdsAttempts });
221
278
  claims = { ...DRIFT_CLAIMS };
222
279
  writeTokenClaims(event, claims);
223
280
  return event;