cdk-local 0.147.9 → 0.147.11

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.
@@ -228,6 +228,395 @@ function buildStsClientConfig(args) {
228
228
  };
229
229
  }
230
230
 
231
+ //#endregion
232
+ //#region src/local/credential-error.ts
233
+ /**
234
+ * Rendering an AWS SDK failure into a log line cdk-local is willing to print
235
+ * at DEFAULT level (issues #564, #570).
236
+ *
237
+ * # Why a shared module
238
+ *
239
+ * Issue #564 settled the policy for one site — the credential-chain failure
240
+ * in {@link file://./sigv4-verify.ts} — and #570 found the same shape at nine
241
+ * more, spread across five `src/cli/commands/*.ts` files. Every one of them
242
+ * relays a third-party error's `message` into a `logger.warn`, so they share
243
+ * one question and must not grow nine answers to it.
244
+ *
245
+ * SCOPE, stated so a later sweep finds a decision rather than an oversight:
246
+ * this module governs those nine plus sigv4-verify's one, and its
247
+ * {@link flattenToOneLine} additionally covers every other wire-derived value
248
+ * printed on those lines (the role ARN, on the failure AND success paths). It
249
+ * does NOT yet govern the AWS SDK error relays elsewhere under
250
+ * `src/local/**` — notably
251
+ * `formatAwsErrorForWarn` (`cfn-local-state-provider.ts`, six warn sites and
252
+ * one non-warn caller)
253
+ * and `formatSsmError` (`ssm-parameter-resolver.ts`), which still print an
254
+ * UNCLAMPED wire-derived `err.name`. Those are enumerated and tracked in
255
+ * issue #579; they were left out here so a cross-cutting refactor of eight
256
+ * more files would not share a review with the policy that justifies it.
257
+ *
258
+ * # The two axes that decide it
259
+ *
260
+ * PROVENANCE alone says relay: a credential-chain error is about the
261
+ * developer's own machine configuration, not something cdk-local fetched out
262
+ * of a secret store (issue #555's criterion). Two further axes overrule it:
263
+ *
264
+ * LEVEL — these are `warn`, so they print on a plain `cdkl start-api` /
265
+ * `cdkl invoke` run rather than only under `--verbose`, and `cdkl studio`
266
+ * mirrors a serve child's output into a log ring it serves over HTTP.
267
+ * Everybody sees a `warn`; only someone who asked sees a `debug`.
268
+ *
269
+ * RECONSTRUCTION — what can reach the string is not a hint about a secret,
270
+ * it is the secret. `@aws-sdk/credential-provider-process` builds its
271
+ * failure as `new CredentialsProviderError(error.message)` where `error` is
272
+ * the rejection of `promisify(child_process.exec)`, i.e. Node's
273
+ * `Command failed: <command line>\n<stderr>`, and a passphrase written on a
274
+ * `credential_process` command line is an ordinary thing to have. (Verified
275
+ * at `@aws-sdk/credential-provider-process@3.972.{39,41,43}`
276
+ * `dist-cjs/index.js:56` in this repo's tree.)
277
+ *
278
+ * # Where these sites DIFFER from sigv4-verify's, and why the answer differs
279
+ *
280
+ * {@link file://./sigv4-verify.ts}'s `catch` wraps `client.config.credentials()`
281
+ * and nothing else: credential-chain resolution, with no AWS operation
282
+ * cdk-local asked for. Nothing actionable is lost by withholding all of it,
283
+ * so that site withholds unconditionally and keeps the text at `debug`.
284
+ *
285
+ * The #570 sites wrap an SDK call cdk-local DID make — STS
286
+ * `GetCallerIdentity` or `AssumeRole` — so two unrelated error populations
287
+ * land in one `catch`:
288
+ *
289
+ * 1. the credential chain failed before the request went out, which is
290
+ * #564's population exactly, and
291
+ * 2. STS answered with a modeled service exception — `ExpiredTokenException`,
292
+ * `AccessDenied` — whose message IS the diagnosis the user needs, and
293
+ * which never went near `credential_process`. (Spelled as the SDK
294
+ * spells them: `@aws-sdk/client-sts` models `ExpiredTokenException`
295
+ * (`dist-cjs/models/errors.js:6`), while `AccessDenied` is unmodeled and
296
+ * arrives as the wire code verbatim — which is exactly why the name is
297
+ * clamped rather than trusted.)
298
+ *
299
+ * Blanket-withholding would turn the single commonest failure of these
300
+ * commands (`ExpiredTokenException: The security token included in the
301
+ * request is expired`) into a class name and a character count. So the split
302
+ * is by population, via {@link describeAwsFailureForWarn}.
303
+ *
304
+ * # The safe state is defined POSITIVELY
305
+ *
306
+ * The discriminator is not a deny-list of bad error shapes — #564 rejected
307
+ * that reasoning for the `Command failed:` first line, and it loses the same
308
+ * race here. It is the SDK's own structural test for "this came off the wire
309
+ * as a modeled service error" ({@link isAwsServiceException}). Anything that
310
+ * does not match — a chain failure, a socket error, a bare `throw 'x'` — is
311
+ * withheld. An unrecognised shape therefore fails toward withholding.
312
+ *
313
+ * A hostile endpoint cannot steer the discriminator into disclosing MORE.
314
+ * `$fault` / `$metadata` are set by the SDK from the HTTP response, not from
315
+ * anything the body names, so forging `x-amzn-errortype:
316
+ * CredentialsProviderError` only changes `err.name` — the response is still a
317
+ * service response, so the error stays on the KEPT branch and its message is
318
+ * still the sanitized, capped one the endpoint could have sent under any
319
+ * other name. What the endpoint cannot do is move a `credential_process`
320
+ * command line onto that branch: that text originates locally, inside a
321
+ * `CredentialsProviderError` that never acquires `$fault`.
322
+ *
323
+ * # What this does NOT close
324
+ *
325
+ * A single-LINE forged string still reaches readers other than a human.
326
+ * `cdkl studio` matches every serve-child stdout line against an unanchored
327
+ * ready-line regex and proxies to the URL it captures, so a message
328
+ * containing `Server listening on http://...` can redirect the studio proxy.
329
+ * That is not fixed here — the sanitizer bounds the line, it does not stop a
330
+ * machine from reading it — and it predates this change (an ordinary handler
331
+ * log line trips the same matcher). Tracked in issue #578.
332
+ */
333
+ /**
334
+ * Longest service-exception message relayed into a `warn` line, in
335
+ * characters.
336
+ *
337
+ * A modeled STS error's message is WIRE-DERIVED — the SDK reads it out of the
338
+ * response body — so its length is not cdk-local's to assume. Real ones run
339
+ * to roughly 150 characters (`AccessDenied: User: arn:... is not authorized to
340
+ * perform: sts:AssumeRole on resource: arn:...`), and the policy-quoting ones
341
+ * are the longest, so the cap is set well above that: it exists to stop an
342
+ * unbounded body from becoming an unbounded log line, not to trim ordinary
343
+ * AWS text, which must survive intact or the branch buys nothing.
344
+ *
345
+ * Truncation is announced with the true length (see
346
+ * {@link sanitizeServiceExceptionMessage}) so a capped line is never mistaken
347
+ * for a complete one.
348
+ */
349
+ const SERVICE_MESSAGE_MAX = 512;
350
+ /**
351
+ * Total stringification of a thrown value's message.
352
+ *
353
+ * `String(err)` is NOT total. That throw would escape the `catch` it is
354
+ * called from and turn a warn-and-continue branch into a hard failure — a 500
355
+ * from the SigV4 authorizer in #564's testing, and a dead `cdkl invoke` here.
356
+ * One helper rather than an expression repeated per site, so the length
357
+ * reported in a `warn` and the text printed at `debug` can never describe
358
+ * different strings.
359
+ *
360
+ * CORRECTION to #564, measured on this repo's Node 24: `String(aSymbol)`
361
+ * does NOT throw — it returns `'Symbol(x)'`, and it is template
362
+ * INTERPOLATION (`` `${aSymbol}` ``) that raises
363
+ * `TypeError: Cannot convert a Symbol value to a string`. Since both the old
364
+ * code and this helper call `String()` explicitly, a `Symbol` throw was never
365
+ * one of the reachable cases. The two that ARE reachable, both verified:
366
+ * an object with a null prototype (`TypeError: Cannot convert object to
367
+ * primitive value`, because it has no `toString`), and any value whose
368
+ * `toString` / `Symbol.toPrimitive` throws — which a hostile or merely buggy
369
+ * third-party error object is free to do.
370
+ *
371
+ * Named for what it does rather than for one caller: #564 shipped it as
372
+ * `stringifyCredentialLoadFailure`, and #570 gave it a second population
373
+ * (service exceptions) for which that name was simply wrong.
374
+ */
375
+ function stringifyThrown(err) {
376
+ try {
377
+ return err instanceof Error ? String(err.message) : String(err);
378
+ } catch {
379
+ return "[unstringifiable throw]";
380
+ }
381
+ }
382
+ /**
383
+ * The throwing class's name, clamped to something no input can forge.
384
+ *
385
+ * `err.name` is NOT input-independent, which is the whole reason this is a
386
+ * function and not an interpolation. For an AWS service exception it is
387
+ * WIRE-DERIVED: `@aws-sdk/core` builds it from the `x-amzn-errortype` header
388
+ * / the body's `code` / `__type` through `sanitizeErrorCode`, which splits on
389
+ * ',' ':' and '#' and does nothing else — no length cap, no newline stripping
390
+ * (read at `@aws-sdk/core@3.974.13` `protocols/index.js:324`). Such an
391
+ * exception reaches these call sites, because `credential-provider-ini` calls
392
+ * the STS `roleAssumer` unwrapped and because the #570 sites invoke STS
393
+ * directly. So a hostile or hijacked credential endpoint
394
+ * (`AWS_CONTAINER_CREDENTIALS_FULL_URI`, a redirected IMDS) answering
395
+ * `x-amzn-errortype: Foo\nWARN: signature verified` could FORGE log lines
396
+ * into the `warn` stream — and into the studio ring served over HTTP.
397
+ *
398
+ * A bare identifier of at most 64 characters is what every real class name is
399
+ * and what no injected value can be; anything else degrades to `'unknown'`,
400
+ * which also covers a non-`Error` throw, so the field never names a class the
401
+ * throw was not.
402
+ *
403
+ * Note the WRONG fix: `err.name.slice(0, 64)` keeps the newline, so the
404
+ * forgery survives truncation.
405
+ */
406
+ function clampErrorName(err) {
407
+ let rawKind;
408
+ try {
409
+ rawKind = err instanceof Error ? err.name : "unknown";
410
+ } catch {
411
+ return "unknown";
412
+ }
413
+ return typeof rawKind === "string" && /^[A-Za-z0-9_.-]{1,64}$/.test(rawKind) ? rawKind : "unknown";
414
+ }
415
+ /**
416
+ * The thrown value's `code`, when it is a bare identifier, else `undefined`.
417
+ *
418
+ * This exists because withholding by class name alone is not discriminating
419
+ * enough for the population that actually reaches the withheld branch most
420
+ * often. `Region is missing`, `getaddrinfo ENOTFOUND sts.<region>.amazonaws.com`
421
+ * and `connect ETIMEDOUT 169.254.169.254:80` all arrive as a plain `Error`, so
422
+ * all three render as `Error; N-character message withheld` and the reader
423
+ * cannot tell a misconfiguration from an unreachable endpoint.
424
+ *
425
+ * Node sets `code` on its system errors (`ENOTFOUND`, `ETIMEDOUT`,
426
+ * `ECONNREFUSED`) and there it is a fixed enum chosen by the runtime. It is
427
+ * NOT input-independent in general, though, and the earlier draft of this note
428
+ * claimed it was: `@smithy/core`'s `decorateServiceException`
429
+ * (`dist-cjs/submodules/client/index.js:795-802`) copies every key of the
430
+ * PARSED RESPONSE BODY onto the exception, so an unmodeled error from a
431
+ * hostile endpoint can carry a `code` of its choosing. The clamp is therefore
432
+ * load-bearing rather than belt-and-braces, exactly as it is for
433
+ * {@link clampErrorName}: what survives is at most 64 characters matching
434
+ * `[A-Za-z0-9_.-]`, which cannot forge a line, and which is the same residue
435
+ * the class name already accepts.
436
+ *
437
+ * `undefined` rather than `'unknown'` when there is none, so the caller can
438
+ * omit the field entirely instead of printing a placeholder that says less
439
+ * than nothing.
440
+ */
441
+ function clampErrorCode(err) {
442
+ if (!err || typeof err !== "object") return void 0;
443
+ let raw;
444
+ try {
445
+ raw = err.code;
446
+ } catch {
447
+ return;
448
+ }
449
+ if (typeof raw !== "string") return void 0;
450
+ return /^[A-Za-z0-9_.-]{1,64}$/.test(raw) ? raw : void 0;
451
+ }
452
+ /**
453
+ * Is `err` a modeled AWS service exception — i.e. did the SDK parse it out of
454
+ * a service RESPONSE, rather than raise it while assembling the request?
455
+ *
456
+ * This is `ServiceException.isInstance`'s own structural test, reproduced
457
+ * rather than imported: cdk-local loads `@aws-sdk/client-sts` lazily at every
458
+ * one of these call sites (a dynamic `import()` inside the `try`), so taking
459
+ * a static dependency on `@smithy/core` purely to type-test an error would
460
+ * pull the SDK into the CLI's startup path. The structural form also keeps
461
+ * working across the several `@smithy/core` copies pnpm resolves in this
462
+ * tree, where an `instanceof` against one copy's class fails for an error
463
+ * minted by another.
464
+ *
465
+ * The test is deliberately the SDK's and not a name list: a name list would
466
+ * have to be extended for every new STS error code, and a missing entry would
467
+ * fail toward DISCLOSING less, which is safe, but also toward hiding the
468
+ * actionable message, which is the regression this split exists to avoid.
469
+ */
470
+ function isAwsServiceException(err) {
471
+ if (!err || typeof err !== "object") return false;
472
+ const candidate = err;
473
+ try {
474
+ return Boolean(candidate.$metadata) && (candidate.$fault === "client" || candidate.$fault === "server");
475
+ } catch {
476
+ return false;
477
+ }
478
+ }
479
+ /**
480
+ * Replace every character that could make one emitted line render as more than
481
+ * one line, or render in an order it was not written in, with a space.
482
+ *
483
+ * Four Unicode categories, each measured rather than assumed (see the fixture
484
+ * in `tests/unit/local/credential-error.test.ts`):
485
+ *
486
+ * - `Cc` — the C0/C1 controls, which is `\n` / `\r` (a forged extra line in
487
+ * the studio ring) and `\x1b` (an ANSI escape in a terminal). U+0085 NEL
488
+ * lives here too.
489
+ * - `Cf` — the format characters, which is U+202E RIGHT-TO-LEFT OVERRIDE and
490
+ * friends: they forge how the REST of the line reads. The cost is that a
491
+ * ZWJ inside an emoji or an Indic cluster is replaced too; an AWS error
492
+ * message is ASCII, so that is a trade with no observed downside.
493
+ * - `Zl` / `Zp` — U+2028 and U+2029. Neither is in `Cc` or `Cf`, and both are
494
+ * forced line breaks in the studio UI's `<pre>`, so leaving them out would
495
+ * have left the forged-line case open in HTML while closing it in a
496
+ * terminal.
497
+ * - `Cs` — a LONE surrogate, which is not a character at all and breaks JSON
498
+ * encoding of the log event. With the `u` flag a well-formed pair is one
499
+ * code point and does NOT match, so emoji survive.
500
+ *
501
+ * Used by both branches of {@link describeAwsFailureForWarn} — the kept
502
+ * message, and the `debug` line carrying the withheld one, because the `debug`
503
+ * stream is the SAME studio ring under `--verbose`, so a text unsafe to put on
504
+ * a line at `warn` is unsafe at `debug` — and, since issue #570's review
505
+ * rounds, by every OTHER wire-derived value that lands on one of these lines:
506
+ * `sigv4-verify`'s own `debug` line, and the role ARN at the four warn sites
507
+ * plus the five `info` / `debug` sites that print an ARN resolved from a live
508
+ * `GetFunctionConfiguration` / `GetAgentRuntime` response. The last group is
509
+ * the more reachable one — it fires on SUCCESS.
510
+ */
511
+ function flattenToOneLine(message) {
512
+ return message.replace(/[\p{Cc}\p{Cf}\p{Zl}\p{Zp}\p{Cs}]/gu, " ");
513
+ }
514
+ /**
515
+ * Render a wire-derived service message safe to put on one log line.
516
+ *
517
+ * Two properties, and both are about the LINE rather than about secrecy — the
518
+ * message itself is already judged safe to print by the time this is called:
519
+ *
520
+ * - No line breaks and no rendering-direction control, via
521
+ * {@link flattenToOneLine}.
522
+ * - Bounded length, with the true length named when it is exceeded. The
523
+ * suffix names the character count of the SANITIZED message rather than
524
+ * of the raw one, because the sanitized string is what the truncated
525
+ * prefix is a prefix OF; quoting the raw length would describe a string
526
+ * the reader can never see.
527
+ *
528
+ * The cut is made on CODE POINTS rather than UTF-16 units, so a truncation
529
+ * landing inside an astral character cannot emit half of a surrogate pair. The
530
+ * count in the suffix is the code-point count for the same reason: the prefix
531
+ * and the number must describe the same string.
532
+ */
533
+ function sanitizeServiceExceptionMessage(message) {
534
+ const points = [...flattenToOneLine(message)];
535
+ if (points.length <= SERVICE_MESSAGE_MAX) return points.join("");
536
+ return `${points.slice(0, SERVICE_MESSAGE_MAX).join("")}[... truncated; ${points.length}-character message]`;
537
+ }
538
+ /**
539
+ * Describe a credential-chain failure for a default-level log line WITHOUT
540
+ * relaying the chain's own message (issue #564).
541
+ *
542
+ * What is reported instead is input-INDEPENDENT: the clamped class name (see
543
+ * {@link clampErrorName}), which is the same discriminator
544
+ * `ecs-secrets-resolver.ts` reports for the JSON parse failure it must not
545
+ * echo, plus the clamped {@link clampErrorCode} when the throw carries one.
546
+ *
547
+ * Withholding is NOT free, and the cost lands on cdk-local's own text as well
548
+ * as on the SDK's: `role-arn.ts`'s
549
+ * `AssumeRole(<arn>) returned no usable credentials.` is a plain `Error` with
550
+ * no `$fault`, so it is withheld like any other. That is a real diagnostic
551
+ * loss, accepted because the alternative — an allow-list of messages that may
552
+ * print — is the deny-list this design rejects, wearing the other sign. The
553
+ * fix is to make cdk-local's own throws identifiable rather than to guess at
554
+ * their text; it is not done here, and is noted in issue #579.
555
+ *
556
+ * The LENGTH is reported, unlike in `ecs-secrets-resolver.ts`, and the
557
+ * difference is deliberate: there the user already knows which secret it is
558
+ * and can read the value at its source, so a character count would be
559
+ * disclosure buying nothing. Here the user cannot see the withheld message at
560
+ * all, and the count is what separates a one-line
561
+ * `Could not load credentials from any providers` (45 characters, measured
562
+ * against `@aws-sdk/credential-provider-node@3.972.44` `dist-cjs/index.js:144`)
563
+ * from a multi-hundred-character `Command failed:` dump — which is what tells
564
+ * them whether their `credential_process` even ran.
565
+ *
566
+ * The count is a side channel, and a narrow one: against a KNOWN
567
+ * `credential_process` template the number is `constant + len(passphrase)`, so
568
+ * it yields the passphrase's LENGTH. That is accepted rather than overlooked.
569
+ * It buys the one thing the user cannot otherwise see, the `Command failed:`
570
+ * dump is not reachable on today's SDK versions anyway, and bucketing the
571
+ * number would blur exactly the boilerplate-vs-dump distinction the field
572
+ * exists for.
573
+ */
574
+ function describeCredentialLoadFailure(err) {
575
+ const code = clampErrorCode(err);
576
+ return `${code === void 0 ? clampErrorName(err) : `${clampErrorName(err)} ${code}`}; ${stringifyThrown(err).length}-character message withheld, logged at debug level under --verbose`;
577
+ }
578
+ /**
579
+ * Render an AWS SDK call failure for a `logger.warn` line, and emit the
580
+ * withheld text at `debug` when it is withheld (issue #570).
581
+ *
582
+ * `operation` names the call for the `debug` line — e.g.
583
+ * `'STS GetCallerIdentity'`. It is cdk-local's own literal at every call
584
+ * site, never anything read off an error or a response.
585
+ *
586
+ * # Why this emits the `debug` line itself
587
+ *
588
+ * Because the alternative is nine call sites each free to withhold a message
589
+ * and forget to print it anywhere. The pairing is the invariant — "withheld
590
+ * at `warn`" is only acceptable while "in full at `debug`" holds — so it
591
+ * lives in one function rather than in a convention nine sites must keep. A
592
+ * tenth site gets it for free.
593
+ *
594
+ * The `debug` line fires ONLY on the withheld branch. On the service-exception
595
+ * branch the `warn` already carries the message, and repeating it verbatim one
596
+ * level down would say nothing the reader did not just read.
597
+ *
598
+ * It is FLATTENED (not capped). Flattened because the `debug` stream is not a
599
+ * private channel: it is the same stdout `cdkl studio` mirrors into the log
600
+ * ring it serves over HTTP, so a `\n` in the withheld text would forge a line
601
+ * there exactly as it would at `warn`. Not capped, because being able to read
602
+ * the whole withheld message is the entire reason the line exists — the
603
+ * `warn`'s character count is what tells the reader how much they are about to
604
+ * see. Note that this puts the full text into that ring for a
605
+ * `--verbose` studio run; see `docs/troubleshooting.md`.
606
+ *
607
+ * ORDERING: the `debug` line is emitted when THIS function runs, which is
608
+ * before the `warn` at every site — inline in the `warn`'s template at eight of
609
+ * them, and a couple of statements earlier at the one that hoists the result
610
+ * into a `const reason`. Either way it prints immediately ABOVE the `warn` that
611
+ * refers to it under `--verbose`. Left as is: restructuring every call site to
612
+ * log afterwards would buy an ordering nobody reads top-down anyway.
613
+ */
614
+ function describeAwsFailureForWarn(err, operation) {
615
+ if (isAwsServiceException(err)) return `${clampErrorName(err)}: ${sanitizeServiceExceptionMessage(stringifyThrown(err))}`;
616
+ getLogger().debug(`${operation}: the AWS SDK's own failure message was: ${flattenToOneLine(stringifyThrown(err))}`);
617
+ return describeCredentialLoadFailure(err);
618
+ }
619
+
231
620
  //#endregion
232
621
  //#region src/utils/role-arn.ts
233
622
  /**
@@ -13421,7 +13810,7 @@ async function verifySigV4(req, loadCredentials, opts = {}) {
13421
13810
  try {
13422
13811
  local = await loadCredentials();
13423
13812
  } catch (err) {
13424
- logger.debug(`AWS_IAM authorizer: the AWS credential chain's own failure message was: ${stringifyCredentialLoadFailure(err)}`);
13813
+ logger.debug(`AWS_IAM authorizer: the AWS credential chain's own failure message was: ${flattenToOneLine(stringifyThrown(err))}`);
13425
13814
  const reason = describeCredentialLoadFailure(err);
13426
13815
  const { sigV4StrictByDefault, sigV4OptFlag: optFlag } = getEmbedConfig();
13427
13816
  if (opts.strict && !opts.oacFronted) {
@@ -13580,60 +13969,6 @@ function redactSignature(signature) {
13580
13969
  return signature;
13581
13970
  }
13582
13971
  /**
13583
- * Describe a credential-chain failure for a default-level log line WITHOUT
13584
- * relaying the chain's own message (issue #564).
13585
- *
13586
- * The message is withheld because of what a credential-chain error CAN
13587
- * carry: `@aws-sdk/credential-provider-process` copies the rejection of
13588
- * `promisify(child_process.exec)` — Node's
13589
- * `Command failed: <command line>\n<stderr>` — into the error it throws, so
13590
- * a passphrase on a `credential_process` command line is already inside a
13591
- * chain error object. On the SDK versions this repo resolves today that
13592
- * object does not actually reach the caller (the chain swallows it and ends
13593
- * on a generic message), which makes this defense in depth rather than a
13594
- * live disclosure. The measurement, and the full reasoning for withholding
13595
- * at `warn` while keeping the text at `debug`, are at the call site in
13596
- * {@link verifySigV4}.
13597
- *
13598
- * What is reported instead is input-INDEPENDENT: `err.name` is set by the
13599
- * throwing class rather than derived from anything the loader read, which is
13600
- * the property that makes quoting it safe, and is the same discriminator
13601
- * `ecs-secrets-resolver.ts` reports for the JSON parse failure it must not
13602
- * echo. `'unknown'` rather than a guessed class name for a non-`Error`
13603
- * throw, so the field never names a class the throw was not -- and the same
13604
- * `'unknown'` for a `name` that is not a bare identifier, so the guarantee
13605
- * does not rest on every provider following the convention.
13606
- *
13607
- * The LENGTH is reported, unlike in `ecs-secrets-resolver.ts`, and the
13608
- * difference is deliberate: there the user already knows which secret it is
13609
- * and can read the value at its source, so a character count would be
13610
- * disclosure buying nothing. Here the user cannot see the withheld message
13611
- * at all, and the count is what separates a one-line
13612
- * `Could not load credentials from any providers` from a multi-hundred-
13613
- * character `Command failed:` dump — which is what tells them whether their
13614
- * `credential_process` even ran. It is the same choice
13615
- * {@link redactAuthorizationSegment} makes when it withholds.
13616
- *
13617
- * The count is a side channel, and a narrow one: against a KNOWN
13618
- * `credential_process` template the number is `constant + len(passphrase)`,
13619
- * so it yields the passphrase's LENGTH. That is accepted rather than
13620
- * overlooked. It buys the one thing the user cannot otherwise see, the
13621
- * `Command failed:` dump is not reachable today anyway (see the call site),
13622
- * and bucketing the number would blur exactly the boilerplate-vs-dump
13623
- * distinction the field exists for.
13624
- */
13625
- function stringifyCredentialLoadFailure(err) {
13626
- try {
13627
- return err instanceof Error ? String(err.message) : String(err);
13628
- } catch {
13629
- return "[unstringifiable throw]";
13630
- }
13631
- }
13632
- function describeCredentialLoadFailure(err) {
13633
- const rawKind = err instanceof Error ? err.name : "unknown";
13634
- return `${/^[A-Za-z0-9_.-]{1,64}$/.test(rawKind) ? rawKind : "unknown"}; ${stringifyCredentialLoadFailure(err).length}-character message withheld, logged at debug level under --verbose`;
13635
- }
13636
- /**
13637
13972
  * How many distinct foreign access-key-ids {@link verifySigV4}'s warn-dedup
13638
13973
  * set retains (issue #561).
13639
13974
  *
@@ -16789,7 +17124,7 @@ function resolveStartApiAssumeRoleArn(args) {
16789
17124
  if (stateBundle) {
16790
17125
  const fromState = resolveExecutionRoleArnFromState(stateBundle.state, logicalId);
16791
17126
  if (fromState) {
16792
- getLogger().info(`--assume-role: auto-resolved execution role for '${logicalId}' from state: ${fromState}`);
17127
+ getLogger().info(`--assume-role: auto-resolved execution role for '${logicalId}' from state: ${flattenToOneLine(fromState)}`);
16793
17128
  return fromState;
16794
17129
  }
16795
17130
  }
@@ -17603,6 +17938,11 @@ async function loadStateForRoutedStacks(stacks, routes, routesWithAuth, options,
17603
17938
  *
17604
17939
  * Region precedence: `--region` > `AWS_REGION` > `AWS_DEFAULT_REGION` >
17605
17940
  * the state record's region (returned by the active `LocalStateProvider`).
17941
+ *
17942
+ * Exported so the issue #570 site-level test can drive the STS failure
17943
+ * branch with a mocked STS client. A helper being correct says nothing about
17944
+ * whether a given site actually routes through it, so each of the nine
17945
+ * converted sites is driven separately.
17606
17946
  */
17607
17947
  async function resolvePseudoParametersForStartApi(stateRegion, options) {
17608
17948
  const logger = getLogger();
@@ -17620,7 +17960,7 @@ async function resolvePseudoParametersForStartApi(stateRegion, options) {
17620
17960
  sts.destroy();
17621
17961
  }
17622
17962
  } catch (err) {
17623
- logger.warn(`--from-state: resolver needs \${AWS::AccountId} but STS GetCallerIdentity failed: ${err instanceof Error ? err.message : String(err)}. Substitution will be skipped for AWS::AccountId; affected env entries will be dropped with per-key warnings.`);
17963
+ logger.warn(`--from-state: resolver needs \${AWS::AccountId} but STS GetCallerIdentity failed: ${describeAwsFailureForWarn(err, "STS GetCallerIdentity")}. Substitution will be skipped for AWS::AccountId; affected env entries will be dropped with per-key warnings.`);
17624
17964
  }
17625
17965
  const partitionAndSuffix = region ? derivePartitionAndUrlSuffix(region) : void 0;
17626
17966
  const bag = {
@@ -18015,6 +18355,15 @@ function envHasCrossStackIntrinsic(templateEnv) {
18015
18355
  }
18016
18356
  return false;
18017
18357
  }
18358
+ /**
18359
+ * Build the AWS pseudo-parameter bag (`${AWS::AccountId}` / `${AWS::Region}` /
18360
+ * partition / URL suffix) that `cdkl invoke`'s env-var substitution consumes.
18361
+ *
18362
+ * Exported so the issue #570 site-level test can drive the STS failure branch
18363
+ * with a mocked STS client -- the same reason `resolveLambdaContainerEnv`
18364
+ * below is exported. A helper being correct says nothing about whether a
18365
+ * given site actually routes through it.
18366
+ */
18018
18367
  async function resolvePseudoParametersForInvoke(stackRegion, options) {
18019
18368
  const logger = getLogger();
18020
18369
  const region = options.region ?? process.env["AWS_REGION"] ?? process.env["AWS_DEFAULT_REGION"] ?? stackRegion;
@@ -18032,7 +18381,7 @@ async function resolvePseudoParametersForInvoke(stackRegion, options) {
18032
18381
  sts.destroy();
18033
18382
  }
18034
18383
  } catch (err) {
18035
- logger.warn(`Resolver needs \${AWS::AccountId} but STS GetCallerIdentity failed: ${err instanceof Error ? err.message : String(err)}. Substitution will be skipped; affected env entries will be dropped with per-key warnings.`);
18384
+ logger.warn(`Resolver needs \${AWS::AccountId} but STS GetCallerIdentity failed: ${describeAwsFailureForWarn(err, "STS GetCallerIdentity")}. Substitution will be skipped; affected env entries will be dropped with per-key warnings.`);
18036
18385
  }
18037
18386
  const partitionAndSuffix = region ? derivePartitionAndUrlSuffix(region) : void 0;
18038
18387
  const bag = {
@@ -18224,8 +18573,8 @@ async function resolveLambdaContainerEnv(lambda, options, profileCredentials, ex
18224
18573
  if (stsRegion) dockerEnv["AWS_REGION"] = stsRegion;
18225
18574
  assumeSucceeded = true;
18226
18575
  } catch (err) {
18227
- const reason = err instanceof Error ? err.message : String(err);
18228
- logger.warn(`--assume-role: STS AssumeRole(${resolvedAssumeRoleArn}) failed: ${reason}. Falling back to the developer's shell credentials.`);
18576
+ const reason = describeAwsFailureForWarn(err, "STS AssumeRole");
18577
+ logger.warn(`--assume-role: STS AssumeRole(${flattenToOneLine(resolvedAssumeRoleArn)}) failed: ${reason}. Falling back to the developer's shell credentials.`);
18229
18578
  }
18230
18579
  }
18231
18580
  if (!assumeSucceeded) {
@@ -18257,10 +18606,23 @@ function materializeInlineCode$1(handler, source, fileExtension) {
18257
18606
  writeFileSync(filePath, source, "utf-8");
18258
18607
  return dir;
18259
18608
  }
18609
+ /**
18610
+ * Suggest `--assume-role` when the deployed function's execution role is
18611
+ * known and the user did not ask for it.
18612
+ *
18613
+ * Exported for the issue #570 ARN-flatten test. This is the MOST reachable of
18614
+ * the sites that print a wire-derived ARN: its caller is guarded on
18615
+ * `options.assumeRole === undefined`, so it fires on a plain
18616
+ * `cdkl invoke --from-cfn-stack <fn>` with no role flag at all. The ARN comes
18617
+ * from the same `resolveExecutionRoleArnFromState` whose other readers are
18618
+ * flattened, `info` is a default level, and `cdkl studio` splits an invoke
18619
+ * child's stdout on `\n` and emits every line as its own ring entry -- so an
18620
+ * unflattened newline here is two entries, the second entirely attacker-chosen.
18621
+ */
18260
18622
  function suggestAssumeRoleFromState(state, logicalId) {
18261
18623
  const logger = getLogger();
18262
18624
  const roleArn = resolveExecutionRoleArnFromState(state, logicalId);
18263
- if (roleArn) logger.info(`Hint: the deployed function uses execution role ${roleArn}. Re-run with --assume-role to invoke under the deployed function's narrow permissions.`);
18625
+ if (roleArn) logger.info(`Hint: the deployed function uses execution role ${flattenToOneLine(roleArn)}. Re-run with --assume-role to invoke under the deployed function's narrow permissions.`);
18264
18626
  }
18265
18627
  /**
18266
18628
  * Resolve the role ARN to assume for a Lambda invoke, honoring the three
@@ -18291,14 +18653,14 @@ async function resolveAssumeRoleArnForLambda(assumeRole, stateForRoleHint, state
18291
18653
  }
18292
18654
  const fromState = resolveExecutionRoleArnFromState(stateForRoleHint, lambdaLogicalId);
18293
18655
  if (fromState) {
18294
- logger.info(`--assume-role: auto-resolved execution role from state: ${fromState}`);
18656
+ logger.info(`--assume-role: auto-resolved execution role from state: ${flattenToOneLine(fromState)}`);
18295
18657
  return fromState;
18296
18658
  }
18297
18659
  const fnPhysicalId = stateForRoleHint.resources[lambdaLogicalId]?.physicalId;
18298
18660
  if (stateProvider?.resolveLambdaExecutionRoleArn && fnPhysicalId) {
18299
18661
  const liveArn = await stateProvider.resolveLambdaExecutionRoleArn(fnPhysicalId);
18300
18662
  if (liveArn) {
18301
- logger.info(`--assume-role: auto-resolved execution role from GetFunctionConfiguration: ${liveArn}`);
18663
+ logger.info(`--assume-role: auto-resolved execution role from GetFunctionConfiguration: ${flattenToOneLine(liveArn)}`);
18302
18664
  return liveArn;
18303
18665
  }
18304
18666
  }
@@ -19864,6 +20226,11 @@ async function buildSigV4HeadersIfRequested(options, resolved, loaded, host, por
19864
20226
  *
19865
20227
  * Throws a {@link CdkLocalError} when none are available — `--sigv4` cannot
19866
20228
  * proceed without credentials, unlike the unsigned path.
20229
+ *
20230
+ * Exported so the issue #570 site-level test can drive the STS failure
20231
+ * branch with a mocked STS client -- the same reason
20232
+ * `applyAgentCoreCredentialEnv` below is exported. A helper being correct
20233
+ * says nothing about whether a given site actually routes through it.
19867
20234
  */
19868
20235
  async function resolveHostCredentialsForSigV4(options, resolved, loaded, region, stateProvider) {
19869
20236
  const logger = getLogger();
@@ -19871,7 +20238,7 @@ async function resolveHostCredentialsForSigV4(options, resolved, loaded, region,
19871
20238
  if (assumeRoleArn) try {
19872
20239
  return await assumeAgentCoreExecutionRole(assumeRoleArn, region, options.profile);
19873
20240
  } catch (err) {
19874
- logger.warn(`--assume-role: STS AssumeRole(${assumeRoleArn}) failed for --sigv4 signing: ${err instanceof Error ? err.message : String(err)}. Falling back to ${options.profile ? `--profile ${options.profile}` : "shell credentials"}.`);
20241
+ logger.warn(`--assume-role: STS AssumeRole(${flattenToOneLine(assumeRoleArn)}) failed for --sigv4 signing: ${describeAwsFailureForWarn(err, "STS AssumeRole (--sigv4 signing)")}. Falling back to ${options.profile ? `--profile ${options.profile}` : "shell credentials"}.`);
19875
20242
  }
19876
20243
  if (options.profile) {
19877
20244
  const creds = await resolveProfileCredentials(options.profile);
@@ -19974,6 +20341,11 @@ async function resolveAgentCoreCodeImage(resolved, code, options, architecture,
19974
20341
  * or resolved from `--from-cfn-stack` state for the bare form) yields STS temp
19975
20342
  * creds for the download; otherwise `--profile` / the default chain is used.
19976
20343
  * The region is `--region` / `--stack-region` / env / the stack's region.
20344
+ *
20345
+ * Exported so the issue #570 site-level test can drive the STS failure
20346
+ * branch with a mocked STS client -- the same reason
20347
+ * `applyAgentCoreCredentialEnv` below is exported. A helper being correct
20348
+ * says nothing about whether a given site actually routes through it.
19977
20349
  */
19978
20350
  async function resolveAgentCoreCodeImageFromS3(resolved, code, s3Source, options, architecture, loaded, stateProvider) {
19979
20351
  const logger = getLogger();
@@ -19989,7 +20361,7 @@ async function resolveAgentCoreCodeImageFromS3(resolved, code, s3Source, options
19989
20361
  if (assumeRoleArn) try {
19990
20362
  credentials = await assumeAgentCoreExecutionRole(assumeRoleArn, region, options.profile);
19991
20363
  } catch (err) {
19992
- logger.warn(`--assume-role: STS AssumeRole(${assumeRoleArn}) failed for the fromS3 bundle download: ${err instanceof Error ? err.message : String(err)}. Falling back to ${options.profile ? `--profile ${options.profile}` : "the default credentials"}.`);
20364
+ logger.warn(`--assume-role: STS AssumeRole(${flattenToOneLine(assumeRoleArn)}) failed for the fromS3 bundle download: ${describeAwsFailureForWarn(err, "STS AssumeRole (fromS3 bundle download)")}. Falling back to ${options.profile ? `--profile ${options.profile}` : "the default credentials"}.`);
19993
20365
  }
19994
20366
  const bundle = await downloadAndExtractS3Bundle(location, {
19995
20367
  ...region !== void 0 && { region },
@@ -20128,7 +20500,7 @@ async function buildAgentCoreImageContext(candidate, stateProvider, options) {
20128
20500
  try {
20129
20501
  accountId = await resolveCallerAccountId$2(region, options.profile);
20130
20502
  } catch (err) {
20131
- logger.warn(`--from-cfn-stack: STS GetCallerIdentity failed: ${err instanceof Error ? err.message : String(err)}. A same-stack ECR image URI referencing \${AWS::AccountId} may not resolve.`);
20503
+ logger.warn(`--from-cfn-stack: STS GetCallerIdentity failed: ${describeAwsFailureForWarn(err, "STS GetCallerIdentity")}. A same-stack ECR image URI referencing \${AWS::AccountId} may not resolve.`);
20132
20504
  }
20133
20505
  const context = {};
20134
20506
  const pseudo = derivePseudoParametersFromRegion(region, accountId);
@@ -20187,7 +20559,7 @@ async function applyAgentCoreCredentialEnv(dockerEnv, args) {
20187
20559
  if (stsRegion) dockerEnv["AWS_REGION"] = stsRegion;
20188
20560
  assumeSucceeded = true;
20189
20561
  } catch (err) {
20190
- logger.warn(`--assume-role: STS AssumeRole(${args.assumeRoleArn}) failed: ${err instanceof Error ? err.message : String(err)}. Falling back to the developer's shell credentials.`);
20562
+ logger.warn(`--assume-role: STS AssumeRole(${flattenToOneLine(args.assumeRoleArn)}) failed: ${describeAwsFailureForWarn(err, "STS AssumeRole")}. Falling back to the developer's shell credentials.`);
20191
20563
  }
20192
20564
  }
20193
20565
  if (!assumeSucceeded) {
@@ -20218,14 +20590,14 @@ async function resolveAssumeRoleArn(options, resolved, loaded, stateProvider) {
20218
20590
  if (loaded) {
20219
20591
  const fromState = resolveExecutionRoleArnFromState(loaded, resolved.logicalId, "RoleArn");
20220
20592
  if (fromState) {
20221
- getLogger().debug(`--assume-role: resolved RoleArn from state: ${fromState}`);
20593
+ getLogger().debug(`--assume-role: resolved RoleArn from state: ${flattenToOneLine(fromState)}`);
20222
20594
  return fromState;
20223
20595
  }
20224
20596
  const runtimePhysicalId = loaded.resources[resolved.logicalId]?.physicalId;
20225
20597
  if (stateProvider?.resolveAgentCoreRuntimeRoleArn && runtimePhysicalId) {
20226
20598
  const liveArn = await stateProvider.resolveAgentCoreRuntimeRoleArn(runtimePhysicalId);
20227
20599
  if (liveArn) {
20228
- getLogger().info(`--assume-role: auto-resolved execution role from GetAgentRuntime: ${liveArn}`);
20600
+ getLogger().info(`--assume-role: auto-resolved execution role from GetAgentRuntime: ${flattenToOneLine(liveArn)}`);
20229
20601
  return liveArn;
20230
20602
  }
20231
20603
  }
@@ -27185,7 +27557,7 @@ async function buildEcsImageResolutionContext$1(target, stacks, options, statePr
27185
27557
  try {
27186
27558
  accountId = await resolveCallerAccountId$1(region, options.profile);
27187
27559
  } catch (err) {
27188
- logger.warn(`Resolver needs \${AWS::AccountId} but STS GetCallerIdentity failed: ${err instanceof Error ? err.message : String(err)}. Substitution will be skipped; affected env / secret entries will be dropped with per-key warnings.`);
27560
+ logger.warn(`Resolver needs \${AWS::AccountId} but STS GetCallerIdentity failed: ${describeAwsFailureForWarn(err, "STS GetCallerIdentity")}. Substitution will be skipped; affected env / secret entries will be dropped with per-key warnings.`);
27189
27561
  }
27190
27562
  const partitionAndSuffix = region ? derivePartitionAndUrlSuffix(region) : void 0;
27191
27563
  ctx.pseudoParameters = {
@@ -27748,7 +28120,7 @@ async function buildEcsImageResolutionContext(candidate, stateProvider, options)
27748
28120
  try {
27749
28121
  accountId = await resolveCallerAccountId(region, options.profile);
27750
28122
  } catch (err) {
27751
- logger.warn(`Resolver needs \${AWS::AccountId} but STS GetCallerIdentity failed: ${err instanceof Error ? err.message : String(err)}. Substitution will be skipped; affected env / secret entries will be dropped with per-key warnings.`);
28123
+ logger.warn(`Resolver needs \${AWS::AccountId} but STS GetCallerIdentity failed: ${describeAwsFailureForWarn(err, "STS GetCallerIdentity")}. Substitution will be skipped; affected env / secret entries will be dropped with per-key warnings.`);
27752
28124
  }
27753
28125
  const partitionAndSuffix = region ? derivePartitionAndUrlSuffix(region) : void 0;
27754
28126
  ctx.pseudoParameters = {
@@ -38059,5 +38431,5 @@ function addStudioSpecificOptions(cmd) {
38059
38431
  }
38060
38432
 
38061
38433
  //#endregion
38062
- export { applyEdgeResponseResult as $, buildJwksUrlFromIssuer as $n, resolveCfnStackName as $r, buildCloudMapIndex as $t, startAgentCoreHttpServer as A, resolveProfileCredentials as Ai, classifySourceChange as An, ConnectionRegistry as Ar, addRunTaskSpecificOptions as At, idFromArn as B, buildStageMap as Bn, resolveRuntimeFileExtension as Br, resolveEcsAssumeRoleOption as Bt, addListSpecificOptions as C, resolveAgentCoreTarget as Ci, waitForAgentCorePing as Cn, tryParseStatus as Cr, parseLbPortOverrides as Ct, createLocalStartAgentCoreCommand as D, tryResolveImageFnJoin as Di, computeCodeImageTag as Dn, probeHostGatewaySupport as Dr, addStartServiceSpecificOptions as Dt, addStartAgentCoreSpecificOptions as E, substituteImagePlaceholders as Ei, buildAgentCoreCodeImage as En, HOST_GATEWAY_MIN_VERSION as Er, resolveAlbFrontDoor as Et, createLocalStartCloudFrontCommand as F, createWatchPredicates as Fn, buildDisconnectEvent as Fr, addImageOverrideOptions as Ft, classifyS3Error as G, filterRoutesByApiIdentifiers as Gn, substituteEnvVarsFromState as Gr, enforceImageOverrideOrphans as Gt, createDeployedKvsDataSource as H, resolveEnvVars$1 as Hn, EcsTaskResolutionError as Hr, runEcsServiceEmulator as Ht, normalizeKvsFileKeys as I, resolveApiTargetSubset as In, buildMessageEvent as Ir, buildEcsImageResolutionContext$1 as It, startCloudFrontServer as J, startApiServer as Jn, createLocalStateProvider as Jr, resolveImageOverrides as Jt, createS3OriginReader as K, groupRoutesByServer as Kn, substituteEnvVarsFromStateAsync as Kr, mergeForService as Kt, parseKvsFileOverrides as L, createAuthorizerCache as Ln, architectureToPlatform as Lr, ecsClusterOption as Lt, startAgentCoreWsBridge as M, createLocalInvokeCommand as Mn, handleConnectionsRequest as Mr, MAX_TASKS_SUBNET_RANGE_CAP as Mt, LocalStartCloudFrontError as N, addStartApiSpecificOptions as Nn, parseConnectionsPath as Nr, addCommonEcsServiceOptions as Nt, buildAgentCoreServeAuthCheck as O, LocalInvokeBuildError as Oi, renderCodeDockerfile as On, resolveHostGatewayExtraHosts as Or, createLocalStartServiceCommand as Ot, addStartCloudFrontSpecificOptions as P, createLocalStartApiCommand as Pn, buildConnectEvent as Pr, addEcsAssumeRoleOptions as Pt, applyEdgeRequestResult as Q, buildCognitoJwksUrl as Qn, resolveCfnRegion as Qr, listPinnedTargets as Qt, parseOriginOverrides as R, createFileWatcher as Rn, buildContainerImage as Rr, parseMaxTasks as Rt, StudioEventBus as S, pickAgentCoreCandidateStack as Si, waitForAgentCoreHttpReady as Sn, selectIntegrationResponse as Sr, createLocalStartAlbCommand as St, formatTargetListing as T, formatStateRemedy as Ti, SUPPORTED_CODE_RUNTIMES as Tn, HOST_DOCKER_INTERNAL_GATEWAY as Tr, isApplicationLoadBalancer as Tt, resolveDeployedKvsArnByName as U, availableApiIdentifiers as Un, substituteAgainstState as Ur, ImageOverrideError as Ut, resolveKvsModulesForDistribution as V, materializeLayerFromArn as Vn, resolveRuntimeImage as Vr, resolveSharedSidecarCredentials as Vt, resolveDeployedOriginBucket as W, filterRoutesByApiIdentifier as Wn, substituteAgainstStateAsync as Wr, buildImageOverrideTag as Wt, serveFromStaticOrigin as X, resolveServiceIntegrationParameters as Xn, rejectExplicitCfnStackWithMultipleStacks as Xr, describePinnedImageUri as Xt, resolveErrorResponseCandidates as Y, resolveSelectionExpression as Yn, isCfnFlagPresent as Yr, runImageOverrideBuilds as Yt, serveLambdaUrlOrigin as Z, defaultCredentialsLoader as Zn, resolveCfnFallbackRegion as Zr, isLocalCdkAssetImage as Zt, filterStudioTargetGroups as _, AGENTCORE_AGUI_PROTOCOL as _i, parseSseForJsonRpc as _n, applyAuthorizerOverlay as _r, createCloudFrontModule as _t, createLocalStudioCommand as a, countTargets as ai, attachContainerLogStreamer as an, computeRequestIdentityHash as ar, describeS3OriginDomain as at, renderStudioHtml as b, AGENTCORE_RUNTIME_TYPE as bi, AGENTCORE_SESSION_ID_HEADER as bn, evaluateResponseParameters as br, addAlbSpecificOptions as bt, startStudioProxy as c, discoverWebSocketApis as ci, bridgeAgentCoreWs as cn, invokeTokenAuthorizer as cr, pickFunctionUrlLogicalIdFromOrigin as ct, createStudioDispatcher as d, parseSelectionExpressionPath as di, A2A_PATH as dn, buildCorsConfigByApiId as dr, pickTargetFunctionLogicalId as dt, CfnLocalStateProvider as ei, CloudMapRegistry as en, createJwksCache as er, buildEdgeRequestEvent as et, filterStudioCustomResources as f, webSocketApiMatchesIdentifier as fi, a2aInvokeOnce as fn, buildCorsConfigFromCloudFrontChain as fr, resolveCloudFrontDistribution as ft, annotatePinnedEcsTargets as g, AGENTCORE_A2A_PROTOCOL as gi, mcpInvokeOnce as gn, translateLambdaResponse as gr, stripCloudFrontImport as gt, annotateEcsTaskPinnedTargets as h, resolveLambdaArnIntrinsic as hi, MCP_PROTOCOL_VERSION as hn, matchRoute as hr, runViewerResponse as ht, coerceStopRequest as i, resolveSingleTarget as ii, getContainerNetworkIp as in, buildMethodArn as ir, CLOUDFRONT_DISTRIBUTION_TYPE as it, attachAgentCoreWsBridge as j, addInvokeSpecificOptions as jn, buildMgmtEndpointEnvUrl as jr, createLocalRunTaskCommand as jt, selectServeInboundAuth as k, buildStsClientConfig as ki, toCmdArgv as kn, bufferToBody as kr, serviceStrategy as kt, relayServeRequest as l, discoverWebSocketApisOrThrow as li, invokeAgentCoreWs as ln, attachAuthorizers as lr, pickKvsLogicalIdFromArn as lt, annotateAlbPinnedBackingServices as m, pickRefLogicalId as mi, MCP_PATH as mn, matchPreflight as mr, runViewerRequest as mt, coerceRunRequest as n, resolveSsmParameters as ni, SOFT_RELOAD_COMPLETION_LOG_SUFFIX as nn, verifyJwtAuthorizer as nr, edgeHeadersToHttp as nt, resolveServeBaseUrl as o, listTargets as oi, addInvokeAgentCoreSpecificOptions as on, evaluateCachedLambdaPolicy as or, extractKvsAssociations as ot, isCustomResourceLambdaTarget as p, discoverRoutes as pi, MCP_CONTAINER_PORT as pn, isFunctionUrlOacFronted as pr, compileCloudFrontFunction as pt, matchBehavior as q, readMtlsMaterialsFromDisk as qn, LocalStateSourceError as qr, parseImageOverrideFlags as qt, coerceServeRequest as r, resolveWatchConfig as ri, setShadowReadyTimeoutMs as rn, verifyJwtViaDiscovery as rr, httpHeadersToEdge as rt, createStudioServeManager as s, availableWebSocketApiIdentifiers as si, createLocalInvokeAgentCoreCommand as sn, invokeRequestAuthorizer as sr, isCloudFrontDistribution as st, addStudioSpecificOptions as t, collectSsmParameterRefs as ti, DEFAULT_SHADOW_READY_TIMEOUT_MS as tn, verifyCognitoJwt as tr, buildEdgeResponseEvent as tt, reinvoke as u, filterWebSocketApisByIdentifiers as ui, A2A_CONTAINER_PORT as un, applyCorsResponseHeaders as ur, pickLambdaEdgeFunctionLogicalId as ut, startStudioServer as v, AGENTCORE_HTTP_PROTOCOL as vi, AGENTCORE_SIGV4_SERVICE as vn, buildHttpApiV2Event as vr, createLocalFileKvsDataSource as vt, createLocalListCommand as w, derivePseudoParametersFromRegion as wi, downloadAndExtractS3Bundle as wn, VtlEvaluationError as wr, resolveAlbTarget as wt, createStudioStore as x, AgentCoreResolutionError as xi, invokeAgentCore as xn, pickResponseTemplate as xr, albStrategy as xt, toStudioTargetGroups as y, AGENTCORE_MCP_PROTOCOL as yi, signAgentCoreInvocation as yn, buildRestV1Event as yr, createUnboundCloudFrontModule as yt, resolveCloudFrontTarget as z, attachStageContext as zn, resolveRuntimeCodeMountPath as zr, parseRestartPolicy as zt };
38063
- //# sourceMappingURL=local-studio-xigfWo5b.js.map
38434
+ export { applyEdgeResponseResult as $, buildJwksUrlFromIssuer as $n, resolveCfnStackName as $r, buildCloudMapIndex as $t, startAgentCoreHttpServer as A, describeCredentialLoadFailure as Ai, classifySourceChange as An, ConnectionRegistry as Ar, addRunTaskSpecificOptions as At, idFromArn as B, buildStageMap as Bn, resolveRuntimeFileExtension as Br, resolveEcsAssumeRoleOption as Bt, addListSpecificOptions as C, resolveAgentCoreTarget as Ci, waitForAgentCorePing as Cn, tryParseStatus as Cr, parseLbPortOverrides as Ct, createLocalStartAgentCoreCommand as D, tryResolveImageFnJoin as Di, computeCodeImageTag as Dn, probeHostGatewaySupport as Dr, addStartServiceSpecificOptions as Dt, addStartAgentCoreSpecificOptions as E, substituteImagePlaceholders as Ei, buildAgentCoreCodeImage as En, HOST_GATEWAY_MIN_VERSION as Er, resolveAlbFrontDoor as Et, createLocalStartCloudFrontCommand as F, createWatchPredicates as Fn, buildDisconnectEvent as Fr, addImageOverrideOptions as Ft, classifyS3Error as G, filterRoutesByApiIdentifiers as Gn, substituteEnvVarsFromState as Gr, enforceImageOverrideOrphans as Gt, createDeployedKvsDataSource as H, resolveEnvVars$1 as Hn, EcsTaskResolutionError as Hr, runEcsServiceEmulator as Ht, normalizeKvsFileKeys as I, resolveApiTargetSubset as In, buildMessageEvent as Ir, buildEcsImageResolutionContext$1 as It, startCloudFrontServer as J, startApiServer as Jn, createLocalStateProvider as Jr, resolveImageOverrides as Jt, createS3OriginReader as K, groupRoutesByServer as Kn, substituteEnvVarsFromStateAsync as Kr, mergeForService as Kt, parseKvsFileOverrides as L, createAuthorizerCache as Ln, architectureToPlatform as Lr, ecsClusterOption as Lt, startAgentCoreWsBridge as M, resolveProfileCredentials as Mi, createLocalInvokeCommand as Mn, handleConnectionsRequest as Mr, MAX_TASKS_SUBNET_RANGE_CAP as Mt, LocalStartCloudFrontError as N, addStartApiSpecificOptions as Nn, parseConnectionsPath as Nr, addCommonEcsServiceOptions as Nt, buildAgentCoreServeAuthCheck as O, LocalInvokeBuildError as Oi, renderCodeDockerfile as On, resolveHostGatewayExtraHosts as Or, createLocalStartServiceCommand as Ot, addStartCloudFrontSpecificOptions as P, createLocalStartApiCommand as Pn, buildConnectEvent as Pr, addEcsAssumeRoleOptions as Pt, applyEdgeRequestResult as Q, buildCognitoJwksUrl as Qn, resolveCfnRegion as Qr, listPinnedTargets as Qt, parseOriginOverrides as R, createFileWatcher as Rn, buildContainerImage as Rr, parseMaxTasks as Rt, StudioEventBus as S, pickAgentCoreCandidateStack as Si, waitForAgentCoreHttpReady as Sn, selectIntegrationResponse as Sr, createLocalStartAlbCommand as St, formatTargetListing as T, formatStateRemedy as Ti, SUPPORTED_CODE_RUNTIMES as Tn, HOST_DOCKER_INTERNAL_GATEWAY as Tr, isApplicationLoadBalancer as Tt, resolveDeployedKvsArnByName as U, availableApiIdentifiers as Un, substituteAgainstState as Ur, ImageOverrideError as Ut, resolveKvsModulesForDistribution as V, materializeLayerFromArn as Vn, resolveRuntimeImage as Vr, resolveSharedSidecarCredentials as Vt, resolveDeployedOriginBucket as W, filterRoutesByApiIdentifier as Wn, substituteAgainstStateAsync as Wr, buildImageOverrideTag as Wt, serveFromStaticOrigin as X, resolveServiceIntegrationParameters as Xn, rejectExplicitCfnStackWithMultipleStacks as Xr, describePinnedImageUri as Xt, resolveErrorResponseCandidates as Y, resolveSelectionExpression as Yn, isCfnFlagPresent as Yr, runImageOverrideBuilds as Yt, serveLambdaUrlOrigin as Z, defaultCredentialsLoader as Zn, resolveCfnFallbackRegion as Zr, isLocalCdkAssetImage as Zt, filterStudioTargetGroups as _, AGENTCORE_AGUI_PROTOCOL as _i, parseSseForJsonRpc as _n, applyAuthorizerOverlay as _r, createCloudFrontModule as _t, createLocalStudioCommand as a, countTargets as ai, attachContainerLogStreamer as an, computeRequestIdentityHash as ar, describeS3OriginDomain as at, renderStudioHtml as b, AGENTCORE_RUNTIME_TYPE as bi, AGENTCORE_SESSION_ID_HEADER as bn, evaluateResponseParameters as br, addAlbSpecificOptions as bt, startStudioProxy as c, discoverWebSocketApis as ci, bridgeAgentCoreWs as cn, invokeTokenAuthorizer as cr, pickFunctionUrlLogicalIdFromOrigin as ct, createStudioDispatcher as d, parseSelectionExpressionPath as di, A2A_PATH as dn, buildCorsConfigByApiId as dr, pickTargetFunctionLogicalId as dt, CfnLocalStateProvider as ei, CloudMapRegistry as en, createJwksCache as er, buildEdgeRequestEvent as et, filterStudioCustomResources as f, webSocketApiMatchesIdentifier as fi, a2aInvokeOnce as fn, buildCorsConfigFromCloudFrontChain as fr, resolveCloudFrontDistribution as ft, annotatePinnedEcsTargets as g, AGENTCORE_A2A_PROTOCOL as gi, mcpInvokeOnce as gn, translateLambdaResponse as gr, stripCloudFrontImport as gt, annotateEcsTaskPinnedTargets as h, resolveLambdaArnIntrinsic as hi, MCP_PROTOCOL_VERSION as hn, matchRoute as hr, runViewerResponse as ht, coerceStopRequest as i, resolveSingleTarget as ii, getContainerNetworkIp as in, buildMethodArn as ir, CLOUDFRONT_DISTRIBUTION_TYPE as it, attachAgentCoreWsBridge as j, buildStsClientConfig as ji, addInvokeSpecificOptions as jn, buildMgmtEndpointEnvUrl as jr, createLocalRunTaskCommand as jt, selectServeInboundAuth as k, describeAwsFailureForWarn as ki, toCmdArgv as kn, bufferToBody as kr, serviceStrategy as kt, relayServeRequest as l, discoverWebSocketApisOrThrow as li, invokeAgentCoreWs as ln, attachAuthorizers as lr, pickKvsLogicalIdFromArn as lt, annotateAlbPinnedBackingServices as m, pickRefLogicalId as mi, MCP_PATH as mn, matchPreflight as mr, runViewerRequest as mt, coerceRunRequest as n, resolveSsmParameters as ni, SOFT_RELOAD_COMPLETION_LOG_SUFFIX as nn, verifyJwtAuthorizer as nr, edgeHeadersToHttp as nt, resolveServeBaseUrl as o, listTargets as oi, addInvokeAgentCoreSpecificOptions as on, evaluateCachedLambdaPolicy as or, extractKvsAssociations as ot, isCustomResourceLambdaTarget as p, discoverRoutes as pi, MCP_CONTAINER_PORT as pn, isFunctionUrlOacFronted as pr, compileCloudFrontFunction as pt, matchBehavior as q, readMtlsMaterialsFromDisk as qn, LocalStateSourceError as qr, parseImageOverrideFlags as qt, coerceServeRequest as r, resolveWatchConfig as ri, setShadowReadyTimeoutMs as rn, verifyJwtViaDiscovery as rr, httpHeadersToEdge as rt, createStudioServeManager as s, availableWebSocketApiIdentifiers as si, createLocalInvokeAgentCoreCommand as sn, invokeRequestAuthorizer as sr, isCloudFrontDistribution as st, addStudioSpecificOptions as t, collectSsmParameterRefs as ti, DEFAULT_SHADOW_READY_TIMEOUT_MS as tn, verifyCognitoJwt as tr, buildEdgeResponseEvent as tt, reinvoke as u, filterWebSocketApisByIdentifiers as ui, A2A_CONTAINER_PORT as un, applyCorsResponseHeaders as ur, pickLambdaEdgeFunctionLogicalId as ut, startStudioServer as v, AGENTCORE_HTTP_PROTOCOL as vi, AGENTCORE_SIGV4_SERVICE as vn, buildHttpApiV2Event as vr, createLocalFileKvsDataSource as vt, createLocalListCommand as w, derivePseudoParametersFromRegion as wi, downloadAndExtractS3Bundle as wn, VtlEvaluationError as wr, resolveAlbTarget as wt, createStudioStore as x, AgentCoreResolutionError as xi, invokeAgentCore as xn, pickResponseTemplate as xr, albStrategy as xt, toStudioTargetGroups as y, AGENTCORE_MCP_PROTOCOL as yi, signAgentCoreInvocation as yn, buildRestV1Event as yr, createUnboundCloudFrontModule as yt, resolveCloudFrontTarget as z, attachStageContext as zn, resolveRuntimeCodeMountPath as zr, parseRestartPolicy as zt };
38435
+ //# sourceMappingURL=local-studio-9eVA5PPS.js.map