@go-to-k/cdkd 0.285.3 → 0.285.4
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/{asg-provider-D3bSjRiw.js → asg-provider-sRJzRAe_.js} +2 -2
- package/dist/{asg-provider-D3bSjRiw.js.map → asg-provider-sRJzRAe_.js.map} +1 -1
- package/dist/cli.js +2 -2
- package/dist/{deploy-engine-3lJaFGjA.js → deploy-engine-3EmPzxSN.js} +467 -41
- package/dist/deploy-engine-3EmPzxSN.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/{program-BU6F1UD2.js → program-DoauTYs2.js} +4 -4
- package/dist/{program-BU6F1UD2.js.map → program-DoauTYs2.js.map} +1 -1
- package/dist/{version-B4YqJKXh.js → version-Dlq6xZAQ.js} +2 -2
- package/dist/{version-B4YqJKXh.js.map → version-Dlq6xZAQ.js.map} +1 -1
- package/package.json +1 -1
- package/dist/deploy-engine-3lJaFGjA.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { d as generateResourceName, f as generateResourceNameWithFallback, g as withStackName, m as looksLikeCdkdGeneratedName, n as getLogger, o as getLiveRenderer, p as getCurrentStackName, u as applyDefaultNameForFallback } from "./logger-Dz3Le2Pw.js";
|
|
2
2
|
import { t as awsClientDefaults } from "./aws-client-defaults-D-iYiIJ6.js";
|
|
3
|
-
import { t as getCdkdVersion } from "./version-
|
|
3
|
+
import { t as getCdkdVersion } from "./version-Dlq6xZAQ.js";
|
|
4
4
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
5
5
|
import { randomUUID } from "node:crypto";
|
|
6
6
|
import { CreateBucketCommand, DeleteObjectCommand, DeleteObjectsCommand, GetBucketLocationCommand, GetObjectCommand, HeadBucketCommand, HeadObjectCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchKey, PutBucketEncryptionCommand, PutBucketPolicyCommand, PutObjectCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
|
|
@@ -11096,22 +11096,35 @@ function dynamicReferenceSpans(value) {
|
|
|
11096
11096
|
* a MIXED leaf than to a whole token on the identical source, and that
|
|
11097
11097
|
* inconsistency is what persisted a decrypted secret.
|
|
11098
11098
|
*
|
|
11099
|
-
*
|
|
11100
|
-
*
|
|
11101
|
-
*
|
|
11102
|
-
*
|
|
11103
|
-
*
|
|
11104
|
-
*
|
|
11105
|
-
*
|
|
11106
|
-
*
|
|
11107
|
-
*
|
|
11108
|
-
*
|
|
11109
|
-
*
|
|
11110
|
-
*
|
|
11111
|
-
*
|
|
11112
|
-
*
|
|
11113
|
-
*
|
|
11114
|
-
*
|
|
11099
|
+
* NOT CLOSED here. Issue
|
|
11100
|
+
* [#2036](https://github.com/go-to-k/cdkd/issues/2036) tracks the price this
|
|
11101
|
+
* refusal pays: a genuinely PUBLIC ssm mixed leaf is OVER-redacted on the
|
|
11102
|
+
* empty-map paths, so the baseline no longer matches AWS. Giving the empty-map
|
|
11103
|
+
* path POSITIVE evidence (a store of PROVEN-public verdicts, which the
|
|
11104
|
+
* resolver's own `pinSecretVerdict` retraction already computes) was drafted in
|
|
11105
|
+
* PR #2415 and WITHDRAWN there: such a store is keyed on the bare expression
|
|
11106
|
+
* and lives for the whole process, so on a `cdkd deploy --all` spanning regions
|
|
11107
|
+
* a verdict recorded where the parameter is a plain `String` un-redacts a
|
|
11108
|
+
* SecureString of the same name in another region — measured, and the
|
|
11109
|
+
* un-redacting direction, which is worse than the over-redaction it fixes. Any
|
|
11110
|
+
* revival must key the verdict by SCOPE (region + account) at the READ side.
|
|
11111
|
+
*
|
|
11112
|
+
* The residual is therefore the whole population an empty map describes, which
|
|
11113
|
+
* is the state issue #2036 records. Refusing is still the right way to be wrong
|
|
11114
|
+
* here: under-redaction persists a decrypted secret, a disclosure and the thing
|
|
11115
|
+
* this lane exists to prevent, while over-redaction is visible, recoverable and
|
|
11116
|
+
* discloses nothing.
|
|
11117
|
+
*
|
|
11118
|
+
* `tests/integration/secrets-dynamic-ref` is the end-to-end proof, and it is
|
|
11119
|
+
* the only place the empty-map defect surfaced — every unit assertion passed.
|
|
11120
|
+
* Three of its phases pin a DIFFERENT map state for the same two leaves, which
|
|
11121
|
+
* is what makes the split observable rather than asserted: Phase 1 is the
|
|
11122
|
+
* populated-map deploy (the resource is being created), Phase 1g the EMPTY-map
|
|
11123
|
+
* deploy (the resource is UNCHANGED, so it has no per-resource map but the
|
|
11124
|
+
* resolver has still classified the parameter this run), and Phase 1f the
|
|
11125
|
+
* empty-map command, which classifies nothing and therefore still refuses. An
|
|
11126
|
+
* earlier revision of this sentence called Phase 1g the populated-map case,
|
|
11127
|
+
* which is the opposite of what that phase is built to reach.
|
|
11115
11128
|
*/
|
|
11116
11129
|
function mixedLeafMayCarryPublicReference(source, secrets) {
|
|
11117
11130
|
if (secrets.size === 0) return false;
|
|
@@ -11267,7 +11280,9 @@ function anchorSignature(source) {
|
|
|
11267
11280
|
*
|
|
11268
11281
|
* Two conditions, both required:
|
|
11269
11282
|
*
|
|
11270
|
-
* 1.
|
|
11283
|
+
* 1. every SOURCE key is present in the bag (objects) or the index counts match
|
|
11284
|
+
* (arrays) — see the object arm for why containment rather than equality,
|
|
11285
|
+
* and which of the two directions is the fabrication guard, and
|
|
11271
11286
|
* 2. every position whose SOURCE carries no dynamic reference is deep-equal on
|
|
11272
11287
|
* both sides -- the *anchors*.
|
|
11273
11288
|
*
|
|
@@ -11307,9 +11322,7 @@ function anchorsCorroboratePairing(bag, source, anchors) {
|
|
|
11307
11322
|
if (isDynamicReferenceString(source)) return typeof bag === "string";
|
|
11308
11323
|
if (isPlainObject$2(source)) {
|
|
11309
11324
|
if (!isPlainObject$2(bag)) return false;
|
|
11310
|
-
|
|
11311
|
-
if (sourceKeys.length !== Object.keys(bag).length) return false;
|
|
11312
|
-
return sourceKeys.every((k) => Object.hasOwn(bag, k) && anchorsCorroboratePairing(bag[k], source[k], anchors));
|
|
11325
|
+
return Object.keys(source).every((k) => Object.hasOwn(bag, k) && anchorsCorroboratePairing(bag[k], source[k], anchors));
|
|
11313
11326
|
}
|
|
11314
11327
|
if (Array.isArray(source)) {
|
|
11315
11328
|
if (!Array.isArray(bag) || bag.length !== source.length) return false;
|
|
@@ -11398,6 +11411,394 @@ function unkeyedArrayPairsByAnchors(bag, source) {
|
|
|
11398
11411
|
return true;
|
|
11399
11412
|
}
|
|
11400
11413
|
/**
|
|
11414
|
+
* Marks a position one of the POSITION passes DECIDED, in the parallel tree
|
|
11415
|
+
* {@link refuseUncertifiedReadbackPositions} builds when asked to `mark`.
|
|
11416
|
+
*
|
|
11417
|
+
* A SENTINEL rather than a value comparison, and that distinction was a
|
|
11418
|
+
* security blocker on PR #2415. {@link preferPositionDecisions} first inferred
|
|
11419
|
+
* "not decided" from `refused === bag`, which cannot tell an UNDECIDED position
|
|
11420
|
+
* from one the pass decided IN FAVOUR of the value already there. Two shapes
|
|
11421
|
+
* hit it, both fabricating a baseline `cdkd drift --revert` then pushes:
|
|
11422
|
+
*
|
|
11423
|
+
* - the resolver's unsupported-service arm leaves an `{{resolve:ssm-secure:`
|
|
11424
|
+
* token LITERAL, so AWS echoes it back and the source leaf EQUALS the bag
|
|
11425
|
+
* leaf. The string arm returns `source` — a decision — and the equality made
|
|
11426
|
+
* it look like no decision at all. (A BARE such token takes the whole-token
|
|
11427
|
+
* arm and one embedded in text takes the mixed-leaf arm; both decide, and
|
|
11428
|
+
* both were misread.)
|
|
11429
|
+
* - the empty-map arm that deliberately KEEPS a leaf returns `bag` by design.
|
|
11430
|
+
*
|
|
11431
|
+
* A symbol cannot be produced by any walk of JSON, so no readback value can
|
|
11432
|
+
* impersonate it.
|
|
11433
|
+
*/
|
|
11434
|
+
const POSITION_DECIDED = Symbol("position decided by a position pass");
|
|
11435
|
+
/**
|
|
11436
|
+
* Record one (plaintext -> expression) pair, or strike the plaintext out.
|
|
11437
|
+
*
|
|
11438
|
+
* Below {@link MIN_NEEDLE_LENGTH} nothing is recorded, and this floor DECIDES
|
|
11439
|
+
* rather than mirrors. {@link buildNeedleRegex} applies the same threshold, so
|
|
11440
|
+
* a short needle is dropped from the SUBSTRING arm either way — but the value
|
|
11441
|
+
* scan's other arm is a WHOLE-VALUE lookup (`secrets.get(leaf)`) that matches
|
|
11442
|
+
* at ANY length, so without this line a two-character derived plaintext would
|
|
11443
|
+
* still rewrite every leaf equal to it. That is the false redaction with a
|
|
11444
|
+
* blast radius {@link expressionMaySeedANeedle} exists to bound, arriving by
|
|
11445
|
+
* length instead of by provenance: a public config value of `us` or `dev` is
|
|
11446
|
+
* exactly the kind of short plaintext a readback carries in a dozen unrelated
|
|
11447
|
+
* fields.
|
|
11448
|
+
*/
|
|
11449
|
+
function learnNeedle(collector, plaintext, expression) {
|
|
11450
|
+
if (plaintext.length < 4) return;
|
|
11451
|
+
if (collector.poisoned.has(plaintext)) return;
|
|
11452
|
+
if (expressionSecretIsInferred(expression)) collector.inferred.add(plaintext);
|
|
11453
|
+
const already = collector.needles.get(plaintext);
|
|
11454
|
+
if (already === void 0) {
|
|
11455
|
+
collector.needles.set(plaintext, expression);
|
|
11456
|
+
return;
|
|
11457
|
+
}
|
|
11458
|
+
if (already === expression) return;
|
|
11459
|
+
collector.needles.delete(plaintext);
|
|
11460
|
+
collector.poisoned.add(plaintext);
|
|
11461
|
+
}
|
|
11462
|
+
/**
|
|
11463
|
+
* The `{{resolve:<service>:` prefixes whose resolved value IS a secret,
|
|
11464
|
+
* whatever the parameter or secret is called.
|
|
11465
|
+
*
|
|
11466
|
+
* `ssm` is in the list and `ssm-secure` is spelled separately, because
|
|
11467
|
+
* `startsWith('{{resolve:ssm:')` is FALSE for `{{resolve:ssm-secure:` — the
|
|
11468
|
+
* next character is `-`. The two are disjoint tests, not one with a prefix
|
|
11469
|
+
* relationship, which is the trap `mixedLeafMayCarryPublicReference`'s own
|
|
11470
|
+
* comment already records from the other direction.
|
|
11471
|
+
*/
|
|
11472
|
+
const SECRET_BEARING_REFERENCE_PREFIXES = [
|
|
11473
|
+
"{{resolve:secretsmanager:",
|
|
11474
|
+
"{{resolve:ssm-secure:",
|
|
11475
|
+
"{{resolve:ssm:"
|
|
11476
|
+
];
|
|
11477
|
+
/**
|
|
11478
|
+
* The prefixes whose SPELLING settles secret-ness, with no lookup and no
|
|
11479
|
+
* inference — the subset of {@link SECRET_BEARING_REFERENCE_PREFIXES} that
|
|
11480
|
+
* {@link expressionSecretIsInferred} treats as certain.
|
|
11481
|
+
*
|
|
11482
|
+
* An ALLOWLIST rather than "the admission list minus `{{resolve:ssm:`", and the
|
|
11483
|
+
* difference is what happens to the NEXT entry someone adds. Subtracting makes a
|
|
11484
|
+
* new prefix default to CERTAIN, i.e. to the WIDER blast radius, which is the
|
|
11485
|
+
* wrong direction to fail in; listing makes it default to inferred until someone
|
|
11486
|
+
* deliberately promotes it.
|
|
11487
|
+
*/
|
|
11488
|
+
const SPELLED_SECRET_REFERENCE_PREFIXES = ["{{resolve:secretsmanager:", "{{resolve:ssm-secure:"];
|
|
11489
|
+
/**
|
|
11490
|
+
* Is this expression's secret-ness INFERRED rather than spelled?
|
|
11491
|
+
*
|
|
11492
|
+
* SPELLING, and ONLY spelling. `secretsmanager:` and `ssm-secure:` say what they
|
|
11493
|
+
* are, in a way that is true in every region and every account. A bare
|
|
11494
|
+
* `{{resolve:ssm:` token is not: it is accepted as secret-bearing on the #1901
|
|
11495
|
+
* premise (a public `String` is persisted RESOLVED, so a token SURVIVING in a
|
|
11496
|
+
* state bag is a `SecureString`), which is sound for the leaf itself and NOT
|
|
11497
|
+
* sound as a licence to rewrite every other leaf that merely CONTAINS the value.
|
|
11498
|
+
*
|
|
11499
|
+
* A RECORDED verdict deliberately does NOT promote one, even though it is a real
|
|
11500
|
+
* `GetParameter` answer. {@link recordedSecretExpressions} is keyed on the bare
|
|
11501
|
+
* expression and lives for the whole process, so on a `cdkd deploy --all` a
|
|
11502
|
+
* verdict pinned where the parameter is a `SecureString` is inherited where it
|
|
11503
|
+
* is a plain `String` — and the `skipDynamicReferences` diff path skips the
|
|
11504
|
+
* lookup on a `true` verdict, so the second region never retracts it. That is
|
|
11505
|
+
* the SAME region blindness this PR withdrew issue #2036's public store for; a
|
|
11506
|
+
* secret-direction verdict is safe to inherit for ADMISSION (it can only
|
|
11507
|
+
* over-redact a leaf) and is not safe for BLAST RADIUS. The cost of ignoring it
|
|
11508
|
+
* here is the substring arm for a verdict-backed, same-region ssm
|
|
11509
|
+
* `SecureString` on the empty-map path — a strict subset of the population the
|
|
11510
|
+
* no-verdict case already concedes, and in the same direction.
|
|
11511
|
+
*
|
|
11512
|
+
* The difference is a `--revert` WRITE. Measured on this module: a bare `ssm`
|
|
11513
|
+
* token whose value is `production` turned `my-production-logs` into
|
|
11514
|
+
* `my-{{resolve:ssm:/app/env}}-logs`, exactly the failure
|
|
11515
|
+
* {@link expressionMaySeedANeedle}'s own doc names — and if that parameter is in
|
|
11516
|
+
* fact public, the baseline now holds a value AWS never reported, which `cdkd
|
|
11517
|
+
* drift --revert` re-resolves and pushes, renaming the live bucket the day the
|
|
11518
|
+
* parameter changes.
|
|
11519
|
+
*
|
|
11520
|
+
* So evidence strength decides BLAST RADIUS, not admission: an inferred needle
|
|
11521
|
+
* still closes issue #2012's two rows, because both are WHOLE-VALUE positions
|
|
11522
|
+
* (an unpaired element and an observed key both hold the plaintext and nothing
|
|
11523
|
+
* else). Only the substring arm is withheld. Issue #2036's withdrawn verdict
|
|
11524
|
+
* store is what would promote these to certain; until it returns, scoped by
|
|
11525
|
+
* region and account, this is the honest bound.
|
|
11526
|
+
*/
|
|
11527
|
+
function expressionSecretIsInferred(expression) {
|
|
11528
|
+
return !SPELLED_SECRET_REFERENCE_PREFIXES.some((prefix) => expression.startsWith(prefix));
|
|
11529
|
+
}
|
|
11530
|
+
/**
|
|
11531
|
+
* May this expression's resolved value be used as a REDACTION NEEDLE?
|
|
11532
|
+
*
|
|
11533
|
+
* A stricter question than "may this expression be persisted at this position",
|
|
11534
|
+
* which is what `trustAnyExpression` answers, and the difference is the whole
|
|
11535
|
+
* reason this predicate exists. Persisting a source leaf VERBATIM is bounded to
|
|
11536
|
+
* that one position; promoting the value it replaced to a needle rewrites EVERY
|
|
11537
|
+
* leaf in the record that equals it, so a wrong answer here is a false
|
|
11538
|
+
* redaction with a blast radius rather than a mislabelled leaf.
|
|
11539
|
+
*
|
|
11540
|
+
* Two classes, and each was measured rather than reasoned about:
|
|
11541
|
+
*
|
|
11542
|
+
* - a NON-SECRET SERVICE. `isSingleDynamicReferenceToken` accepts any
|
|
11543
|
+
* `{{resolve:<anything>}}` spelling, and the resolver's unsupported-service
|
|
11544
|
+
* arm WARNS and returns the literal — so AWS holds the token text itself and
|
|
11545
|
+
* the leaf beside it is ordinary data. `cdkd drift`'s own
|
|
11546
|
+
* `--revert does not register a live value for a look-alike spelling` case
|
|
11547
|
+
* pins exactly this for its sibling registration path
|
|
11548
|
+
* (`{{resolve:notaservice:/x}}`), and this predicate is what keeps the two
|
|
11549
|
+
* commands answering it the same way.
|
|
11550
|
+
* - a plain `ssm` reference is ACCEPTED, on the same
|
|
11551
|
+
* #1901 premise the whole-token arm one level up already acts on: a public
|
|
11552
|
+
* `String` / `StringList` parameter is persisted RESOLVED, so a
|
|
11553
|
+
* `{{resolve:ssm:` token SURVIVING in a persisted state bag is a
|
|
11554
|
+
* `SecureString` by construction. Requiring a recorded verdict instead would
|
|
11555
|
+
* make the needle unavailable on `cdkd state refresh-observed`, whose process
|
|
11556
|
+
* resolves nothing and therefore records nothing — i.e. it would fail exactly
|
|
11557
|
+
* where issue #2012 is reported. A PROVEN-public verdict would refine this,
|
|
11558
|
+
* and issue #2036's store was to supply one; PR #2415 withdrew it as a
|
|
11559
|
+
* cross-region disclosure, so a genuinely public parameter's resolved value
|
|
11560
|
+
* CAN still seed a needle here. Bounded by the per-record scope and by
|
|
11561
|
+
* {@link MIN_NEEDLE_LENGTH}, and visible as over-redaction rather than as a
|
|
11562
|
+
* leak.
|
|
11563
|
+
*/
|
|
11564
|
+
function expressionMaySeedANeedle(expression) {
|
|
11565
|
+
return isRecordedSecretExpression(expression) || SECRET_BEARING_REFERENCE_PREFIXES.some((prefix) => expression.startsWith(prefix));
|
|
11566
|
+
}
|
|
11567
|
+
/**
|
|
11568
|
+
* Learn from a position whose SOURCE is a WHOLE `{{resolve:...}}` token.
|
|
11569
|
+
*
|
|
11570
|
+
* This is the strongest needle available on a readback path, and it asserts
|
|
11571
|
+
* nothing the walk was not already asserting: the caller is about to persist
|
|
11572
|
+
* `expression` OVER `bag` at this very position, which is the claim that `bag`
|
|
11573
|
+
* is that expression's resolved value. Reading the same claim back out as a
|
|
11574
|
+
* needle is free.
|
|
11575
|
+
*
|
|
11576
|
+
* TWO refusals, both narrow and both necessary:
|
|
11577
|
+
*
|
|
11578
|
+
* - a bag leaf that is ITSELF a complete token is not a plaintext at all. It is
|
|
11579
|
+
* a record that was already redacted (a re-scrub, a second
|
|
11580
|
+
* `refresh-observed`), and pairing it with itself would put a `{{resolve:...}}`
|
|
11581
|
+
* string in the needle set, where the value scan's own token guard would then
|
|
11582
|
+
* have to keep stepping over it.
|
|
11583
|
+
* - a token that does not name a SECRET-BEARING reference at all — see
|
|
11584
|
+
* {@link expressionMaySeedANeedle}.
|
|
11585
|
+
*/
|
|
11586
|
+
function learnWholeTokenNeedle(collector, bag, source) {
|
|
11587
|
+
if (isSingleDynamicReferenceToken(bag)) return;
|
|
11588
|
+
if (!expressionMaySeedANeedle(source)) return;
|
|
11589
|
+
learnNeedle(collector, bag, source);
|
|
11590
|
+
}
|
|
11591
|
+
/**
|
|
11592
|
+
* Learn from a MIXED leaf — a reference embedded in surrounding text, which
|
|
11593
|
+
* this module calls the DOMINANT CDK shape (an `Fn::Join` around
|
|
11594
|
+
* `secret.secretValueFromJson(...)`).
|
|
11595
|
+
*
|
|
11596
|
+
* The caller is about to persist `source` over `bag`, i.e. it has already
|
|
11597
|
+
* decided the two are the same leaf one resolution apart. Extracting the
|
|
11598
|
+
* plaintext is then arithmetic rather than inference, PROVIDED the extraction
|
|
11599
|
+
* is unambiguous, which is what the guards below establish:
|
|
11600
|
+
*
|
|
11601
|
+
* - EXACTLY ONE span. With two references the text between them cannot be
|
|
11602
|
+
* split between the two resolved values without guessing. This one is
|
|
11603
|
+
* CONSERVATIVE rather than a correctness guard, and saying so is what stops
|
|
11604
|
+
* the next reader treating it as load-bearing: with two RESOLVED references
|
|
11605
|
+
* the frame check below refuses independently, because the computed SUFFIX
|
|
11606
|
+
* would then contain a whole `{{resolve:...}}` token and a resolved readback
|
|
11607
|
+
* cannot end with one. The shape it genuinely decides is a second reference
|
|
11608
|
+
* that survives LITERALLY in the readback — the resolver's
|
|
11609
|
+
* unsupported-service arm (`ssm-secure:`) produces exactly that — where the
|
|
11610
|
+
* extraction would in fact be right and is declined anyway. Measured: a
|
|
11611
|
+
* both-resolved fixture leaves this line unfenced.
|
|
11612
|
+
* - the source's literal PREFIX and SUFFIX must both be present at the ends of
|
|
11613
|
+
* the bag. That is what proves the leaf really is this source resolved; AWS
|
|
11614
|
+
* normalising any of the surrounding text refuses instead of yielding a
|
|
11615
|
+
* needle sliced at the wrong offsets.
|
|
11616
|
+
* - the two must not overlap, and something must remain between them.
|
|
11617
|
+
*
|
|
11618
|
+
* Anchoring at the ENDS rather than searching is deliberate: a secret whose own
|
|
11619
|
+
* text repeats the suffix (`abc@h` inside `postgres://u:abc@h@h`) still slices
|
|
11620
|
+
* correctly, while an `indexOf` scan would cut it short.
|
|
11621
|
+
*/
|
|
11622
|
+
function learnMixedLeafNeedle(collector, bag, source) {
|
|
11623
|
+
const spans = dynamicReferenceSpans(source);
|
|
11624
|
+
if (spans.length !== 1) return;
|
|
11625
|
+
const [span] = spans;
|
|
11626
|
+
const token = source.slice(span.start, span.end);
|
|
11627
|
+
if (!expressionMaySeedANeedle(token)) return;
|
|
11628
|
+
const prefix = source.slice(0, span.start);
|
|
11629
|
+
const suffix = source.slice(span.end);
|
|
11630
|
+
if (bag.length <= prefix.length + suffix.length) return;
|
|
11631
|
+
if (!bag.startsWith(prefix) || !bag.endsWith(suffix)) return;
|
|
11632
|
+
const plaintext = bag.slice(prefix.length, bag.length - suffix.length);
|
|
11633
|
+
if (isSingleDynamicReferenceToken(plaintext)) return;
|
|
11634
|
+
learnNeedle(collector, plaintext, token);
|
|
11635
|
+
}
|
|
11636
|
+
/**
|
|
11637
|
+
* Read the mark tree one level down. It has the SAME shape as `refused` by
|
|
11638
|
+
* construction (one function, one set of inputs), but this stays defensive: a
|
|
11639
|
+
* missing level yields `undefined`, which reads as "not decided" and therefore
|
|
11640
|
+
* lets the scan act. That is the same answer the pre-mark code gave, so a shape
|
|
11641
|
+
* surprise cannot silently start SUPPRESSING redaction — but it fails toward
|
|
11642
|
+
* SCANNING, which is the fabrication direction the mark tree exists to stop.
|
|
11643
|
+
* Both are stated because neither default is free; the shapes are identical by
|
|
11644
|
+
* construction (one function, one set of inputs), so this arm is a backstop
|
|
11645
|
+
* rather than a policy.
|
|
11646
|
+
*/
|
|
11647
|
+
function asChild(marks, key) {
|
|
11648
|
+
return isPlainObject$2(marks) && hasPlainPrototype(marks) ? marks[key] : void 0;
|
|
11649
|
+
}
|
|
11650
|
+
/** The array-arm twin of {@link asChild}; same fail-open, same reason. */
|
|
11651
|
+
function asIndex(marks, index) {
|
|
11652
|
+
return Array.isArray(marks) ? marks[index] : void 0;
|
|
11653
|
+
}
|
|
11654
|
+
/**
|
|
11655
|
+
* Merge the DERIVED-needle value scan back over the two POSITION passes, so the
|
|
11656
|
+
* scan can only ever ADD a rewrite and never EDIT one.
|
|
11657
|
+
*
|
|
11658
|
+
* WHY THIS EXISTS AT ALL. Issue #2012's fix has been through both orderings and
|
|
11659
|
+
* each has its own way of turning a redaction fix into a fabricated baseline —
|
|
11660
|
+
* the two are mirror images, which is why the answer is a merge rather than a
|
|
11661
|
+
* third choice of order:
|
|
11662
|
+
*
|
|
11663
|
+
* - SCAN FIRST (the first revision): a needle rewrites a frame LITERAL that
|
|
11664
|
+
* happens to embed a learned plaintext, {@link unkeyedArrayPairsByAnchors} is
|
|
11665
|
+
* then re-run against the SCANNED bag, the anchor no longer deep-equals its
|
|
11666
|
+
* source, the whole array refuses, and a sibling MIXED leaf that position
|
|
11667
|
+
* ALREADY redacted persists in plaintext. Under-redaction.
|
|
11668
|
+
* - SCAN LAST, unrestricted (the second): the scan now runs over leaves whose
|
|
11669
|
+
* content came from the SOURCE. A needle occurring in the literal FRAME of a
|
|
11670
|
+
* source-taken mixed leaf is replaced, so
|
|
11671
|
+
* `postgres://appuser:{{resolve:secretsmanager:...}}@h/db` becomes
|
|
11672
|
+
* `postgres://{{resolve:ssm:/app/db-user}}:{{resolve:...}}@h/db` when
|
|
11673
|
+
* `appuser` is also some whole-token position's resolved value — a reference
|
|
11674
|
+
* the template never had at that offset. `cdkd drift --revert` re-resolves the
|
|
11675
|
+
* baseline before pushing it, so once that parameter's value changes the
|
|
11676
|
+
* revert writes a DIFFERENT user to the live resource. Fabricated baseline,
|
|
11677
|
+
* which is the bar {@link refuseUncertifiedReadbackPositions} refuses to break
|
|
11678
|
+
* at its own bottom.
|
|
11679
|
+
*
|
|
11680
|
+
* THE RULE. A position the passes DECIDED is theirs; a position they left alone
|
|
11681
|
+
* belongs to the scan. Expressed as a walk over their OUTPUT rather than as a
|
|
11682
|
+
* second copy of their pairing logic, because a mirror of `identityKeyFor` /
|
|
11683
|
+
* `unkeyedArrayPairsByAnchors` would drift from the original and a needle
|
|
11684
|
+
* applied at a MIS-paired position is a false redaction everywhere it matches.
|
|
11685
|
+
* The shapes line up position-for-position for free: neither pass adds a key,
|
|
11686
|
+
* an element, or a scalar-over-container, so `refused` is `bag`'s own shape with
|
|
11687
|
+
* some leaves replaced.
|
|
11688
|
+
*
|
|
11689
|
+
* `typeof bag === 'string'` at the leaf: a derived needle can only ever rewrite
|
|
11690
|
+
* a STRING, so for every other leaf the two answers agree and taking `refused`
|
|
11691
|
+
* is free.
|
|
11692
|
+
*
|
|
11693
|
+
* KEEPING A NON-PLAIN LEAF INTACT takes the prototype guard on the object arm,
|
|
11694
|
+
* NOT that leaf rule, and an earlier revision of this comment claimed the
|
|
11695
|
+
* opposite — measured wrong. The scan's own walk rebuilds objects and turns a
|
|
11696
|
+
* `Date` the provider readback carries (`LastModified`) into `{}`; that
|
|
11697
|
+
* flattening predates this module's derived needles on the POPULATED-map path
|
|
11698
|
+
* (issue #2427). The object arm runs FIRST here and `isPlainObject` admits a
|
|
11699
|
+
* `Date`, so without `hasPlainPrototype` this walk did the flattening ITSELF —
|
|
11700
|
+
* newly extending #2427 to the EMPTY-map path, where the unchanged-resource
|
|
11701
|
+
* `drainObservedCaptures` baseline lives and where `cdkd drift --revert` pushes
|
|
11702
|
+
* the result to the live resource. With the guard a non-plain leaf falls
|
|
11703
|
+
* through to `refused`. That is the position passes' own answer — usually the
|
|
11704
|
+
* bag by identity, though NOT universally: their object arm has no prototype
|
|
11705
|
+
* guard of its own, so a non-plain leaf whose source subtree carries a
|
|
11706
|
+
* reference is already flattened one function earlier. Same defect as issue
|
|
11707
|
+
* #2427, one layer up, and out of this lane's scope.
|
|
11708
|
+
*
|
|
11709
|
+
* The net effect is byte-identical to the FIRST ordering on every input where
|
|
11710
|
+
* the un-certification did not fire — which is the whole point: it keeps that
|
|
11711
|
+
* ordering's intent and drops only its defect.
|
|
11712
|
+
*/
|
|
11713
|
+
function preferPositionDecisions(scanned, refused, bag, marks, inferred) {
|
|
11714
|
+
if (isPlainObject$2(bag) && hasPlainPrototype(bag) && isPlainObject$2(refused) && isPlainObject$2(scanned)) {
|
|
11715
|
+
const out = Object.create(null);
|
|
11716
|
+
for (const [k, v] of Object.entries(refused)) out[k] = preferPositionDecisions(scanned[k], v, bag[k], asChild(marks, k), inferred);
|
|
11717
|
+
return out;
|
|
11718
|
+
}
|
|
11719
|
+
if (Array.isArray(bag) && Array.isArray(refused) && Array.isArray(scanned) && refused.length === bag.length && scanned.length === bag.length) return refused.map((item, i) => preferPositionDecisions(scanned[i], item, bag[i], asIndex(marks, i), inferred));
|
|
11720
|
+
if (typeof bag !== "string" || marks === POSITION_DECIDED) return refused;
|
|
11721
|
+
return scanned === bag ? inferred.get(bag) ?? scanned : scanned;
|
|
11722
|
+
}
|
|
11723
|
+
/**
|
|
11724
|
+
* DERIVED NEEDLES (issue [#2012](https://github.com/go-to-k/cdkd/issues/2012)):
|
|
11725
|
+
* the secrets map an empty-map readback path can build from its OWN two bags,
|
|
11726
|
+
* with no resolution, no AWS call and no new permission.
|
|
11727
|
+
*
|
|
11728
|
+
* THE PROBLEM THIS ANSWERS. On the readback paths the secrets map is empty by
|
|
11729
|
+
* construction (nothing was resolved), so the value scan has no needles and
|
|
11730
|
+
* POSITION is the only mechanism. Two shapes have no position to argue from and
|
|
11731
|
+
* kept their plaintext: an UNPAIRED array element beside a paired one, and an
|
|
11732
|
+
* observed KEY the source does not carry. Both are places {@link redactByPath}
|
|
11733
|
+
* ALREADY delegates to the value scan — it is the scan that had nothing to say.
|
|
11734
|
+
*
|
|
11735
|
+
* WHAT MAKES A NEEDLE AVAILABLE WITHOUT FETCHING. The same record almost always
|
|
11736
|
+
* carries the same secret at a position the pass DOES certify: the paired
|
|
11737
|
+
* sibling, the key the source does carry. Certifying such a position IS the
|
|
11738
|
+
* assertion that AWS's value there is that expression's resolved form — the
|
|
11739
|
+
* pass acts on it by persisting the expression over it. Reading that assertion
|
|
11740
|
+
* back out gives a plaintext, and a plaintext is exactly what the value scan
|
|
11741
|
+
* was missing. Issue #2012's own direction was to RESOLVE the record's
|
|
11742
|
+
* expressions to get one, which would have made `cdkd state refresh-observed`
|
|
11743
|
+
* and every deploy's observed capture FETCH secrets: a new IAM requirement, a
|
|
11744
|
+
* new failure mode and a new place plaintext lives. None of that is needed —
|
|
11745
|
+
* AWS already handed us the plaintext, in the very bag being redacted.
|
|
11746
|
+
*
|
|
11747
|
+
* `redactByPath`'s own comment argued the opposite direction and was right
|
|
11748
|
+
* about it: seeding the scan from the SOURCE's expressions cannot work, because
|
|
11749
|
+
* a scan needs PLAINTEXT needles. This seeds it from the BAG's values, which is
|
|
11750
|
+
* the half that exists.
|
|
11751
|
+
*
|
|
11752
|
+
* SCOPE, and why each bound is where it is:
|
|
11753
|
+
*
|
|
11754
|
+
* - ONLY the readback-projected rules. Every other caller either has a real map
|
|
11755
|
+
* or has a source of a different generation, where a value learned from one
|
|
11756
|
+
* generation must not rewrite the other.
|
|
11757
|
+
* - ONLY when the map is EMPTY, and this bound is load-bearing for a reason
|
|
11758
|
+
* that is not obvious: {@link crossStackAssociations} and
|
|
11759
|
+
* {@link nestedStackParameterExpressions} are `WeakMap`s keyed by the
|
|
11760
|
+
* RecordedSecretValues INSTANCE, so handing the pipeline a different Map
|
|
11761
|
+
* object would silently lose every association that pass recorded. With an
|
|
11762
|
+
* empty map there are none to lose (an association is only ever recorded for
|
|
11763
|
+
* a plaintext that map holds).
|
|
11764
|
+
* - the pairs are scoped to ONE record, exactly as `perResourceSecrets` is on
|
|
11765
|
+
* the deploy path, so one resource's secret can never rewrite another's
|
|
11766
|
+
* coinciding literal.
|
|
11767
|
+
*
|
|
11768
|
+
* WHERE THE RESULT IS APPLIED, and this is a SEQUENCING claim rather than a
|
|
11769
|
+
* scoping one: the returned map is handed to a plain VALUE pass over the RAW
|
|
11770
|
+
* bag, whose result is then MERGED over the output of both position passes by
|
|
11771
|
+
* {@link preferPositionDecisions}. It reaches neither position pass. Both naive
|
|
11772
|
+
* orderings are wrong and that function's doc has the measurements: scanning
|
|
11773
|
+
* FIRST lets a needle rewrite a frame LITERAL and un-certify an anchor pairing
|
|
11774
|
+
* (under-redaction), scanning LAST over their output lets one rewrite a literal
|
|
11775
|
+
* inside a leaf they took from SOURCE (a fabricated baseline). The merge is what
|
|
11776
|
+
* makes "a derived needle can only ADD rewrites" literally true.
|
|
11777
|
+
*
|
|
11778
|
+
* Returns `undefined` when nothing is learned, so the no-secret path skips the
|
|
11779
|
+
* scan and the merge entirely and stays byte-identical to the position passes'
|
|
11780
|
+
* own output.
|
|
11781
|
+
*/
|
|
11782
|
+
function deriveReadbackNeedles(bag, source, secrets, rules) {
|
|
11783
|
+
if (!isReadbackProjectedFromState(rules)) return void 0;
|
|
11784
|
+
if (secrets.size > 0) return void 0;
|
|
11785
|
+
if (!subtreeHasDynamicReference(source)) return void 0;
|
|
11786
|
+
const collector = {
|
|
11787
|
+
needles: /* @__PURE__ */ new Map(),
|
|
11788
|
+
poisoned: /* @__PURE__ */ new Set(),
|
|
11789
|
+
inferred: /* @__PURE__ */ new Set()
|
|
11790
|
+
};
|
|
11791
|
+
refuseUncertifiedReadbackPositions(bag, source, secrets, collector);
|
|
11792
|
+
if (collector.needles.size === 0) return void 0;
|
|
11793
|
+
const certain = /* @__PURE__ */ new Map();
|
|
11794
|
+
const inferred = /* @__PURE__ */ new Map();
|
|
11795
|
+
for (const [plaintext, expression] of collector.needles) (collector.inferred.has(plaintext) ? inferred : certain).set(plaintext, expression);
|
|
11796
|
+
return {
|
|
11797
|
+
certain,
|
|
11798
|
+
inferred
|
|
11799
|
+
};
|
|
11800
|
+
}
|
|
11801
|
+
/**
|
|
11401
11802
|
* Refuse to persist a readback leaf the path pass could not CERTIFY, at any
|
|
11402
11803
|
* position the STATE source proves is secret-bearing (issue #1926 review).
|
|
11403
11804
|
*
|
|
@@ -11482,39 +11883,59 @@ function unkeyedArrayPairsByAnchors(bag, source) {
|
|
|
11482
11883
|
* --revert` pushes the BASELINE to AWS, so a masked baseline would write the
|
|
11483
11884
|
* literal `***` onto the live resource (the issue #1498 / #1501 class).
|
|
11484
11885
|
*
|
|
11485
|
-
*
|
|
11486
|
-
*
|
|
11487
|
-
*
|
|
11488
|
-
*
|
|
11489
|
-
*
|
|
11490
|
-
*
|
|
11491
|
-
*
|
|
11492
|
-
*
|
|
11493
|
-
*
|
|
11494
|
-
|
|
11495
|
-
|
|
11886
|
+
* The last two rows were the RESIDUAL and are closed by DERIVED NEEDLES (issue
|
|
11887
|
+
* #2012) — see {@link deriveReadbackNeedles}. Neither has a position to argue
|
|
11888
|
+
* from: an unpaired array element and an observed KEY the source does not carry
|
|
11889
|
+
* are both positions with no source leaf to take. What they never lacked was a
|
|
11890
|
+
* VALUE — the same plaintext usually sits at a position this pass DOES certify,
|
|
11891
|
+
* and certifying it is already an assertion that the value is that expression's
|
|
11892
|
+
* resolved form. Reading that assertion back out as a needle turns the value
|
|
11893
|
+
* scan on for the rest of the record without resolving anything.
|
|
11894
|
+
*
|
|
11895
|
+
* The extra-KEY asymmetry stays as it was and is worth restating, because the
|
|
11896
|
+
* needle does not replace it: an extra array element is a PEER of the
|
|
11897
|
+
* secret-bearing ones (another `Environment` entry), while an extra object KEY
|
|
11898
|
+
* is a different FIELD entirely (`Runtime`, `FunctionArn`, `LastModified`) and
|
|
11899
|
+
* is the NORM in an AWS readback. Refusing those wholesale would empty the
|
|
11900
|
+
* drift baseline of every secret-bearing resource, which is why they are
|
|
11901
|
+
* value-scanned rather than refused.
|
|
11902
|
+
*
|
|
11903
|
+
* `learn` is the LEARN PASS's collector and is `undefined` on the substituting
|
|
11904
|
+
* pass. It changes NO verdict — every branch below decides exactly what it
|
|
11905
|
+
* decided before — it only records the (plaintext, expression) pairs the
|
|
11906
|
+
* certified positions establish. Deriving them through this function rather
|
|
11907
|
+
* than a second walk is deliberate: the pairing rules (identity keys, anchor
|
|
11908
|
+
* corroboration, the refusals) are subtle enough that a mirror of them would
|
|
11909
|
+
* drift, and a needle learned from a MIS-paired position is a false redaction
|
|
11910
|
+
* everywhere it then matches.
|
|
11911
|
+
*/
|
|
11912
|
+
function refuseUncertifiedReadbackPositions(bag, source, secrets, learn, mark) {
|
|
11496
11913
|
if (isDynamicReferenceString(source) && typeof bag === "string") {
|
|
11497
|
-
if (isSingleDynamicReferenceToken(source))
|
|
11498
|
-
|
|
11499
|
-
|
|
11914
|
+
if (isSingleDynamicReferenceToken(source)) {
|
|
11915
|
+
if (learn) learnWholeTokenNeedle(learn, bag, source);
|
|
11916
|
+
return mark ? POSITION_DECIDED : source;
|
|
11917
|
+
}
|
|
11918
|
+
if (mixedLeafMayCarryPublicReference(source, secrets)) return mark ? POSITION_DECIDED : bag;
|
|
11919
|
+
if (learn) learnMixedLeafNeedle(learn, bag, source);
|
|
11920
|
+
return mark ? POSITION_DECIDED : source;
|
|
11500
11921
|
}
|
|
11501
11922
|
if (!subtreeHasDynamicReference(source)) return bag;
|
|
11502
11923
|
if (isPlainObject$2(bag) && isPlainObject$2(source)) {
|
|
11503
11924
|
const out = Object.create(null);
|
|
11504
|
-
for (const [k, v] of Object.entries(bag)) out[k] = Object.hasOwn(source, k) ? refuseUncertifiedReadbackPositions(v, source[k], secrets) : v;
|
|
11925
|
+
for (const [k, v] of Object.entries(bag)) out[k] = Object.hasOwn(source, k) ? refuseUncertifiedReadbackPositions(v, source[k], secrets, learn, mark) : v;
|
|
11505
11926
|
return out;
|
|
11506
11927
|
}
|
|
11507
11928
|
if (Array.isArray(bag) && Array.isArray(source)) {
|
|
11508
11929
|
const key = identityKeyFor(bag, source);
|
|
11509
11930
|
if (key === void 0) {
|
|
11510
11931
|
if (!unkeyedArrayPairsByAnchors(bag, source)) return bag;
|
|
11511
|
-
return bag.map((item, i) => refuseUncertifiedReadbackPositions(item, source[i], secrets));
|
|
11932
|
+
return bag.map((item, i) => refuseUncertifiedReadbackPositions(item, source[i], secrets, learn, mark));
|
|
11512
11933
|
}
|
|
11513
11934
|
const sourceByIdentity = /* @__PURE__ */ new Map();
|
|
11514
11935
|
for (const item of source) sourceByIdentity.set(item[key], item);
|
|
11515
11936
|
return bag.map((item) => {
|
|
11516
11937
|
const partner = sourceByIdentity.get(item[key]);
|
|
11517
|
-
return partner === void 0 ? item : refuseUncertifiedReadbackPositions(item, partner, secrets);
|
|
11938
|
+
return partner === void 0 ? item : refuseUncertifiedReadbackPositions(item, partner, secrets, learn, mark);
|
|
11518
11939
|
});
|
|
11519
11940
|
}
|
|
11520
11941
|
return bag;
|
|
@@ -11532,7 +11953,12 @@ function redactSecretsForState(bag, secrets, source, rules = TEMPLATE_DERIVED_RU
|
|
|
11532
11953
|
if (secrets.size === 0 && source === void 0) return bag;
|
|
11533
11954
|
if (source !== void 0) {
|
|
11534
11955
|
const positioned = redactByPath(bag, source, secrets, rules, new Set(secrets.values()));
|
|
11535
|
-
|
|
11956
|
+
if (!isReadbackProjectedFromState(rules)) return positioned;
|
|
11957
|
+
const refused = refuseUncertifiedReadbackPositions(positioned, source, secrets);
|
|
11958
|
+
const derived = deriveReadbackNeedles(bag, source, secrets, rules);
|
|
11959
|
+
if (derived === void 0) return refused;
|
|
11960
|
+
const marks = refuseUncertifiedReadbackPositions(positioned, source, secrets, void 0, true);
|
|
11961
|
+
return preferPositionDecisions(redactSecretsForState(bag, derived.certain), refused, bag, marks, derived.inferred);
|
|
11536
11962
|
}
|
|
11537
11963
|
const regex = buildNeedleRegex(secrets.keys());
|
|
11538
11964
|
const wholeValueExpr = (s) => s === "" ? void 0 : secrets.get(s);
|
|
@@ -20729,7 +21155,7 @@ var CloudControlProvider = class {
|
|
|
20729
21155
|
await this.confirmDeleteTargetIdentity(logicalId, resourceType, physicalId, context);
|
|
20730
21156
|
if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
|
|
20731
21157
|
this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
|
|
20732
|
-
const { ASGProvider } = await import("./asg-provider-
|
|
21158
|
+
const { ASGProvider } = await import("./asg-provider-sRJzRAe_.js").then((n) => n.n);
|
|
20733
21159
|
return await new ASGProvider().delete(logicalId, physicalId, resourceType, _properties, context);
|
|
20734
21160
|
}
|
|
20735
21161
|
const isProtectedEc2Instance = context?.removeProtection === true && resourceType === "AWS::EC2::Instance";
|
|
@@ -32718,4 +33144,4 @@ var DeployEngine = class {
|
|
|
32718
33144
|
|
|
32719
33145
|
//#endregion
|
|
32720
33146
|
export { maskerOrIdentity as $, CFN_TEMPLATE_BODY_LIMIT as $n, maskSecretsInText as $t, renderStatefulReason as A, describeAwsFailure as An, PartialFailureError as Ar, requireConfigString as At, exportAliasCollisionScrubWarning as B, Synthesizer as Bn, normalizeAwsError as Br, INTRINSIC_KEYS as Bt, isFinalSnapshotError as C, getBootstrapMarkerKey as Cn, DynamicReferenceRegionAmbiguousError as Cr, coerceCfnBoolean as Ct, extractDeploymentEventError as D, validateAssetBucketName as Dn, LockError as Dr, replayWarn as Dt, makeCanonicalizePropertiesFn as E, readBootstrapMarkerBody as En, LocalStartServiceError as Er, readConfigString as Et, green as F, partitionSensitiveEnv as Fn, StackTerminationProtectionError as Fr, s3BucketDualStackDomainName as Ft, IAMRoleProvider as G, resolveAutoAssetStorage as Gn, isTransientServerError as Gr, STATE_SOURCED_CROSS_GENERATION_RULES as Gt, secretBearingStateKeyWarning as H, getDefaultStateBucketName as Hn, isMarkedNonRetryable as Hr, withRetry as Ht, red as I, runDockerForeground as In, StateError as Ir, s3BucketRegionalDomainName as It, ProviderRegistry as J, resolveStateBucketWithDefault as Jn, retryClassificationText as Jr, createSecretMasker as Jt, collectInlinePolicyNamesManagedBySiblings as K, resolveCaptureObservedState as Kn, markNonRetryable as Kr, STATE_SOURCED_READBACK_RULES as Kt, yellow as L, runDockerStreaming as Ln, SynthesisError as Lr, s3BucketWebsiteUrl as Lt, bold as M, dockerSpawnEnvWithSensitive as Mn, ResourceTimeoutError as Mr, producerRegionsFromState as Mt, cyan as N, formatDockerLoginError as Nn, ResourceUpdateNotSupportedError as Nr, s3BucketArn as Nt, MULTI_REGION_RECREATE_BLOCKED_TYPES as O, validateContainerRepoName as On, MissingCdkCliError as Or, requireConfigArray as Ot, gray as P, getDockerCmd as Pn, StackHasActiveImportsError as Pr, s3BucketDomainName as Pt, maskDeep as Q, warnDeprecatedNoPrefixCliFlag as Qn, maskSecretsInError as Qt, collectDeclaredOutputNames as R, AssetManifestLoader as Rn, formatError as Rr, applyRoleArnIfSet as Rt, createPreDeleteFinalSnapshot as S, ensureAssetStorage as Sn, DeployCancelledError as Sr, assertRegionMatch as St, unsupportedFinalSnapshotError as T, parseBootstrapMarker as Tn, LocalMigrateError as Tr, configStringRefusal as Tt, stateKeySecretExposure as U, getLegacyStateBucketName as Un, isRetryableTransientError as Ur, DagBuilder as Ut, isExportAliasCollision as V, synthesisStatusMessage as Vn, withErrorHandling as Vr, describeTypeWithThrottleRetry as Vt, getCurrentResourceSecrets as W, resolveApp as Wn, isThrottlingError as Wr, TemplateParser as Wt, findSilentDropProperties as X, resolveUseCdkBootstrapAssets as Xn, errorCauseChain as Xt, findActionableSilentDrops as Y, resolveStateBucketWithDefaultAndSource as Yn, __exportAll as Yr, dynamicReferenceTokens as Yt, createMaskedRetryLogger as Z, stateBucketExistenceConfirmed as Zn, isSingleDynamicReferenceToken as Zt, computeImplicitDeleteEdges as _, escapeRegExp$1 as _n, AssetError as _r, parameterTypeMayLoseSecretIdentity as _t, DeploymentEventsStore as a, rebuildClientForBucketRegion as an, expectedOwnerParam as ar, isInterruptedWaitError as at, buildFinalSnapshotIdentifier as b, BOOTSTRAP_MARKER_PREFIX as bn, CrossAccountSecretRefusalError as br, normalizeAwsTagsToCfn as bt, replayFailedOperations as c, importableOutputs as cn, derivePartitionAndUrlSuffix as cr, slowCcOperationTimeoutMs as ct, updatePartialReason as d, stringifyValue as dn, clearBucketRegionCache as dr, IntrinsicFunctionResolver as dt, redactSecretsForState as en, CFN_TEMPLATE_URL_LIMIT as er, CUSTOM_RESOURCE_RESPONSE_PREFIX as et, UNSPECIFIED_SKIP_REASON as f, WorkGraph as fn, resolveBucketRegion as fr, carriesDynamicReference as ft, IMPLICIT_DELETE_DEPENDENCIES as g, rewriteTemplateAssetReferences as gn, setAwsClients as gr, isUnboundTemplateParameter as gt, maskingRetryLogger as h, loadPublishableAssetManifest as hn, resetAwsClients as hr, getAccountInfo as ht, DeploymentEventsReader as i, S3StateBackend as in, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as ir, interruptWatchListenerCount as it, formatResourceLine as j, buildDockerImage as jn, ProvisioningError as jr, classifyReplaySecretRegion as jt, isStatefulRecreateTargetSync as k, buildDenyExternalAccessPolicy as kn, NestedStackChildDirectDestroyError as kr, requireConfigObject as kt, replayRollback as l, shouldRetainResource as ln, AssemblyReader as lr, disableInstanceApiTermination as lt, withResourceDeadline as m, createAssetRedirectResolver as mn, getAwsClients as mr, coerceParameterTypedValue as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, LockManager as nn, findLargeInlineResources as nr, beginCommandInterruptScope as nt, planFailedOps as o, exportNamesCarriedFrom as on, PARTITION_TABLE as or, startInterruptWatch as ot, deleteSkipReason as p, buildAssetRedirectMap as pn, AwsClients as pr, cfnRefValueFromPhysicalId as pt, clearOnUpdateRemoval as q, resolveSkipPrefix as qn, markRedactedCause as qr, TEMPLATE_SOURCED_RULES as qt, DeployEngine as r, displaySafe as rn, uploadCfnTemplate as rr, endCommandInterruptScope as rt, planRollback as s, importableOutputKeys as sn, canonicalizeRegion as sr, CloudControlProvider as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, scrubResourceRecord as tn, MIGRATE_TMP_PREFIX as tr, DEFAULT_STATE_PREFIX as tt, updatePartialMessage as u, AssetPublisher as un, processStackMessages as ur, isTerminationProtectionPropagationError as ut, ATOMIC_FINAL_SNAPSHOT_TYPES as v, stripControlChars as vn, CdkdError as vr, refStateLookupFromResource as vt, refusesFinalSnapshot as w, isCrossRegionRedirect as wn, LocalInvokeBuildError as wr, configBooleanRefusal as wt, ccRoutedFinalSnapshotError as x, assertAssetBucketRegion as xn, DependencyError as xr, resolveExplicitPhysicalId as xt, PRE_DELETE_SNAPSHOT_TYPES as y, AssetModeResolver as yn, ConfigError as yr, WAFv2WebACLProvider as yt, collectPublishedOutputNames as z, getDockerImageBySourceHash as zn, isCdkdError as zr, DiffCalculator as zt };
|
|
32721
|
-
//# sourceMappingURL=deploy-engine-
|
|
33147
|
+
//# sourceMappingURL=deploy-engine-3EmPzxSN.js.map
|