cdk-local 0.165.1 → 0.166.1
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/README.md +2 -0
- package/dist/{aws-proxy-CtjweaLu.js → aws-proxy-Ba_BOPyi.js} +5 -2
- package/dist/{aws-proxy-CtjweaLu.js.map → aws-proxy-Ba_BOPyi.js.map} +1 -1
- package/dist/cli.js +2 -2
- package/dist/{docker-cmd-Cqd0TG-d.js → docker-cmd-BnW-0c0e.js} +2 -2
- package/dist/{docker-cmd-Cqd0TG-d.js.map → docker-cmd-BnW-0c0e.js.map} +1 -1
- package/dist/{docker-runner-CmcChp3e.js → docker-runner-DjcP2syq.js} +230 -9
- package/dist/docker-runner-DjcP2syq.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/internal.d.ts +1 -1
- package/dist/internal.js +5 -5
- package/dist/{local-studio-XwDqTyvC.d.ts → local-studio-BF_pYaBC.d.ts} +11 -1
- package/dist/local-studio-BF_pYaBC.d.ts.map +1 -0
- package/dist/{local-studio-Y_GECnu7.js → local-studio-PpZpeKYn.js} +234 -70
- package/dist/local-studio-PpZpeKYn.js.map +1 -0
- package/dist/{workload-identity-BONcukjU.js → workload-identity-Blv2g1Jp.js} +2 -2
- package/dist/{workload-identity-BONcukjU.js.map → workload-identity-Blv2g1Jp.js.map} +1 -1
- package/package.json +2 -1
- package/dist/docker-runner-CmcChp3e.js.map +0 -1
- package/dist/local-studio-XwDqTyvC.d.ts.map +0 -1
- package/dist/local-studio-Y_GECnu7.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { a as displayIdent, c as getEmbedConfig, i as STACK_REF_MAX_CODE_POINTS, o as displayStackName, s as displayToolOutput, t as getLogger, u as setEmbedConfig } from "./logger-uzapot2X.js";
|
|
2
|
-
import { $ as formatHostForAuthority, B as describeCredentialLoadFailure, H as isAwsServiceException, I as renderAssemblyPathEscape, J as resolveEnvVars$1, K as applyEnvOverrideMap, L as resolveAssemblyPath, N as displayUntrustedValue, Q as formatAuthority, R as clampErrorName, U as sanitizeServiceExceptionMessage, V as flattenToOneLine, W as stringifyThrown, X as isLoopbackHostname, Y as defineOwnKey, Z as isWildcardHostname, et as hostFromAuthority, j as absoluteAssemblyPathEscape, n as awsEmulatorRealServices, o as deployArtifactClientConfig, p as proxyAwareFetch, q as readEnvVarsFileText, r as awsEndpointOverrideClientConfig, s as deployArtifactsReadEmulator, u as isAwsServiceRoutedToEmulator, y as createMixedModeStateProvider, z as describeAwsFailureForWarn } from "./aws-proxy-
|
|
3
|
-
import { $ as isIamRoleArn, A as buildDockerImage, B as substituteImagePlaceholders, D as isImageInLocalCache, E as warnIfEmulatedPlatform, F as parseEcrRegistryHost, G as LocalStartServiceError, H as CdkLocalError, I as contextForContainer, J as withErrorHandling, K as RouteDiscoveryError, L as derivePartitionAndUrlSuffix, M as createShutdownSignalHandler, N as signalExitCode, O as parseEcrUri, P as describeExitWithoutArgv, Q as describeRejectedRoleArn, R as derivePseudoParametersFromRegion, T as buildContainerImage, U as InteractiveTtyRequiredError, V as tryResolveImageFnJoin, W as LocalInvokeBuildError, X as applyRoleArnIfSet, Y as AssumeRoleFailure, Z as assumeRoleCredentials, a as describeRefusedSensitiveEnvKeys, c as execEnvForSecrets, d as rememberForwardedPorts, et as refusedRoleArnMessage, f as removeContainer, h as streamLogs, i as attachLoopbackForwarder, j as resolveAssetSourcePath, k as pullEcrImage, l as pickFreePort, m as startNamespaceOwnerForwarder, n as SENSITIVE_ENV_KEYS, nt as
|
|
4
|
-
import { C as effectiveLoopbackPorts, F as resolveHostDefaultCredentials, R as takeAwsEmulatorStateSourceHint, b as awsEmulatorEnvName, d as workloadStsClientConfig, l as warnWorkloadCredentialsStripped, n as accountLookupStsClientConfig, r as applyWorkloadEnvCredentials, u as workloadClientConfig, v as activateWorkloadAwsWiring, w as getActiveWorkloadAwsWiring, y as applyWorkloadAwsWiringToEnv, z as workloadGetsEmulatorKeysOnly } from "./workload-identity-
|
|
5
|
-
import { a as isDockerClientEnvKey, c as runDockerStreaming, i as getDockerCmd, n as finchSecretArgvRefusal, o as isMalformedEnvKey, p as noImplicitEcrPullArgs, u as warnFinchArgvExposure } from "./docker-cmd-
|
|
2
|
+
import { $ as formatHostForAuthority, B as describeCredentialLoadFailure, H as isAwsServiceException, I as renderAssemblyPathEscape, J as resolveEnvVars$1, K as applyEnvOverrideMap, L as resolveAssemblyPath, N as displayUntrustedValue, Q as formatAuthority, R as clampErrorName, U as sanitizeServiceExceptionMessage, V as flattenToOneLine, W as stringifyThrown, X as isLoopbackHostname, Y as defineOwnKey, Z as isWildcardHostname, et as hostFromAuthority, j as absoluteAssemblyPathEscape, n as awsEmulatorRealServices, o as deployArtifactClientConfig, p as proxyAwareFetch, q as readEnvVarsFileText, r as awsEndpointOverrideClientConfig, s as deployArtifactsReadEmulator, u as isAwsServiceRoutedToEmulator, y as createMixedModeStateProvider, z as describeAwsFailureForWarn } from "./aws-proxy-Ba_BOPyi.js";
|
|
3
|
+
import { $ as isIamRoleArn, A as buildDockerImage, B as substituteImagePlaceholders, D as isImageInLocalCache, E as warnIfEmulatedPlatform, F as parseEcrRegistryHost, G as LocalStartServiceError, H as CdkLocalError, I as contextForContainer, J as withErrorHandling, K as RouteDiscoveryError, L as derivePartitionAndUrlSuffix, M as createShutdownSignalHandler, N as signalExitCode, O as parseEcrUri, P as describeExitWithoutArgv, Q as describeRejectedRoleArn, R as derivePseudoParametersFromRegion, T as buildContainerImage, U as InteractiveTtyRequiredError, V as tryResolveImageFnJoin, W as LocalInvokeBuildError, X as applyRoleArnIfSet, Y as AssumeRoleFailure, Z as assumeRoleCredentials, a as describeRefusedSensitiveEnvKeys, c as execEnvForSecrets, d as rememberForwardedPorts, et as refusedRoleArnMessage, f as removeContainer, h as streamLogs, i as attachLoopbackForwarder, j as resolveAssetSourcePath, k as pullEcrImage, l as pickFreePort, m as startNamespaceOwnerForwarder, n as SENSITIVE_ENV_KEYS, nt as buildStsClientConfig, p as runDetached, q as TargetSelectionCancelledError, r as appendEnvFlags, rt as resolveProfileCredentials, s as ensureDockerAvailable, t as DockerRunnerError, tt as emulateRoleAfterDeniedAssume, u as pullImage, w as architectureToPlatform, z as formatStateRemedy } from "./docker-runner-DjcP2syq.js";
|
|
4
|
+
import { C as effectiveLoopbackPorts, F as resolveHostDefaultCredentials, R as takeAwsEmulatorStateSourceHint, b as awsEmulatorEnvName, d as workloadStsClientConfig, l as warnWorkloadCredentialsStripped, n as accountLookupStsClientConfig, r as applyWorkloadEnvCredentials, u as workloadClientConfig, v as activateWorkloadAwsWiring, w as getActiveWorkloadAwsWiring, y as applyWorkloadAwsWiringToEnv, z as workloadGetsEmulatorKeysOnly } from "./workload-identity-Blv2g1Jp.js";
|
|
5
|
+
import { a as isDockerClientEnvKey, c as runDockerStreaming, i as getDockerCmd, n as finchSecretArgvRefusal, o as isMalformedEnvKey, p as noImplicitEcrPullArgs, u as warnFinchArgvExposure } from "./docker-cmd-BnW-0c0e.js";
|
|
6
6
|
import { chmodSync, cpSync, createWriteStream, existsSync, lstatSync, mkdirSync, mkdtempSync, promises, readFileSync, readdirSync, readlinkSync, realpathSync, rmSync, statSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
|
|
7
7
|
import { Command, InvalidArgumentError, Option } from "commander";
|
|
8
8
|
import { STSClient } from "@aws-sdk/client-sts";
|
|
@@ -79,6 +79,21 @@ function appOptions() {
|
|
|
79
79
|
return [new Option("-a, --app <command>", `CDK app command (e.g., "node app.ts") or path to a pre-synthesized cloud assembly directory. Falls back to cdk.json or ${envPrefix}_APP env`), new Option("--output <path>", "Output directory for synthesis").default("cdk.out")];
|
|
80
80
|
}
|
|
81
81
|
const contextOptions = [new Option("-c, --context <key=value...>", "Set context values (can be specified multiple times)")];
|
|
82
|
+
function parseEmulateRoleVia(raw) {
|
|
83
|
+
const arn = raw.trim();
|
|
84
|
+
if (!isIamRoleArn(arn)) throw new InvalidArgumentError(`Invalid --emulate-role-via value ${describeRejectedRoleArn(raw)}: expected an IAM role ARN like arn:aws:iam::123456789012:role/MyRole.`);
|
|
85
|
+
return arn;
|
|
86
|
+
}
|
|
87
|
+
function emulateRoleViaOption(roleFlag) {
|
|
88
|
+
return new Option("--emulate-role-via <arn>", `When the ${roleFlag} AssumeRole is refused (the role does not trust you), emulate the role's permissions: assume THIS role with the execution role's policies as session policies, so only what both allow is allowed. For callers that are not an IAM user (IAM Identity Center, a role session); an IAM user gets the same through sts:GetFederationToken without this flag. An approximation: resource-based policies, key policies and conditions naming the role are not reproduced, and a role with a permissions boundary is not emulated.`).argParser(parseEmulateRoleVia);
|
|
89
|
+
}
|
|
90
|
+
function isRoleFlagRequested(value) {
|
|
91
|
+
return value === true || typeof value === "string";
|
|
92
|
+
}
|
|
93
|
+
function warnIfEmulateRoleViaUnused(value, args) {
|
|
94
|
+
if (value === void 0 || args.roleRequested) return;
|
|
95
|
+
getLogger().warn(`--emulate-role-via has no effect without ${args.roleFlag}: it is used only when that flag's AssumeRole is refused.`);
|
|
96
|
+
}
|
|
82
97
|
function parseAssumeRoleToken(raw, previous) {
|
|
83
98
|
const acc = previous ?? { perLambda: {} };
|
|
84
99
|
if (!acc.perLambda) acc.perLambda = {};
|
|
@@ -4259,6 +4274,7 @@ function detectEcsImageResolutionNeeds(stack) {
|
|
|
4259
4274
|
let needsStateResources = false;
|
|
4260
4275
|
let needsEnvOrSecretSubstitution = false;
|
|
4261
4276
|
let needsCrossStackResolver = false;
|
|
4277
|
+
let needsTaskRoleState = false;
|
|
4262
4278
|
for (const res of Object.values(resources)) {
|
|
4263
4279
|
if (res.Type !== "AWS::ECS::TaskDefinition") continue;
|
|
4264
4280
|
const props = res.Properties ?? {};
|
|
@@ -4283,13 +4299,15 @@ function detectEcsImageResolutionNeeds(stack) {
|
|
|
4283
4299
|
break;
|
|
4284
4300
|
}
|
|
4285
4301
|
}
|
|
4302
|
+
if (sameStackRoleLogicalId(props["TaskRoleArn"], resources) !== void 0) needsTaskRoleState = true;
|
|
4286
4303
|
if (isFnJoinOrSubIntrinsic(props["TaskRoleArn"]) || isFnJoinOrSubIntrinsic(props["ExecutionRoleArn"])) needsEnvOrSecretSubstitution = true;
|
|
4287
4304
|
}
|
|
4288
4305
|
return {
|
|
4289
4306
|
needsPseudoParameters,
|
|
4290
4307
|
needsStateResources,
|
|
4291
4308
|
needsEnvOrSecretSubstitution,
|
|
4292
|
-
needsCrossStackResolver
|
|
4309
|
+
needsCrossStackResolver,
|
|
4310
|
+
needsTaskRoleState
|
|
4293
4311
|
};
|
|
4294
4312
|
}
|
|
4295
4313
|
function containerHasCrossStackEnvOrSecret(c) {
|
|
@@ -4487,8 +4505,13 @@ function extractTaskDefinitionProperties(stack, logicalId, resource, context) {
|
|
|
4487
4505
|
if (props["ProxyConfiguration"]) warnings.push(`Task definition ${displayIdent(logicalId)} declares 'ProxyConfiguration' (custom Envoy / App Mesh bootstrap), which is NOT honored by '${getEmbedConfig().cliName} start-service' / '${getEmbedConfig().cliName} run-task' in v1. Local execution will run without the configured proxy. See design doc § 2 for the rationale.`);
|
|
4488
4506
|
const resources = stack.template.Resources ?? {};
|
|
4489
4507
|
const subContext = buildSubstitutionContextFromImageContext(context);
|
|
4490
|
-
const
|
|
4491
|
-
|
|
4508
|
+
const roleSubContext = context?.ignoreStateForRoles && subContext ? {
|
|
4509
|
+
...subContext,
|
|
4510
|
+
resources: Object.fromEntries(Object.entries(subContext.resources).filter(([, r]) => r.resourceType !== "AWS::IAM::Role"))
|
|
4511
|
+
} : subContext;
|
|
4512
|
+
const taskRole = resolveRoleArn(props["TaskRoleArn"], resources, roleSubContext);
|
|
4513
|
+
const taskRoleArn = taskRole.arn;
|
|
4514
|
+
const executionRoleArn = resolveRoleArn(props["ExecutionRoleArn"], resources, roleSubContext).arn;
|
|
4492
4515
|
const runtimePlatform = parseRuntimePlatform(props["RuntimePlatform"]);
|
|
4493
4516
|
const rawContainers = props["ContainerDefinitions"];
|
|
4494
4517
|
if (!Array.isArray(rawContainers) || rawContainers.length === 0) throw new EcsTaskResolutionError(`Task definition ${displayIdent(logicalId)} has no ContainerDefinitions.`);
|
|
@@ -4513,6 +4536,7 @@ function extractTaskDefinitionProperties(stack, logicalId, resource, context) {
|
|
|
4513
4536
|
warnings
|
|
4514
4537
|
};
|
|
4515
4538
|
if (taskRoleArn !== void 0) out.taskRoleArn = taskRoleArn;
|
|
4539
|
+
if (taskRole.unresolved !== void 0) out.taskRoleUnresolved = taskRole.unresolved;
|
|
4516
4540
|
if (executionRoleArn !== void 0) out.executionRoleArn = executionRoleArn;
|
|
4517
4541
|
if (runtimePlatform !== void 0) out.runtimePlatform = runtimePlatform;
|
|
4518
4542
|
return out;
|
|
@@ -4886,10 +4910,20 @@ function resolveVolumeSourcePath(raw, volumeName, idx, taskLogicalId, subContext
|
|
|
4886
4910
|
throw new EcsTaskResolutionError(`Task ${displayIdent(taskLogicalId)} Volumes[${idx}] ${displayIdent(volumeName)} Host.SourcePath could not be resolved: ` + (sub.kind === "literal" ? "resolved to non-string / empty value" : sub.reason));
|
|
4887
4911
|
}
|
|
4888
4912
|
const TASK_ROLE_ACCOUNT_PLACEHOLDER = "${AWS::AccountId}";
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4913
|
+
const TASK_ROLE_PARTITION_PLACEHOLDER = "${AWS::Partition}";
|
|
4914
|
+
function placeholderRoleArn(pathAndName) {
|
|
4915
|
+
return `arn:${TASK_ROLE_PARTITION_PLACEHOLDER}:iam::${TASK_ROLE_ACCOUNT_PLACEHOLDER}:role${pathAndName}`;
|
|
4916
|
+
}
|
|
4917
|
+
function fillTaskRolePlaceholders(arn, account, callerArn) {
|
|
4918
|
+
const segment = callerArn?.split(":")[1];
|
|
4919
|
+
const partition = callerArn?.startsWith("arn:") && segment ? segment : "aws";
|
|
4920
|
+
return arn.split(TASK_ROLE_ACCOUNT_PLACEHOLDER).join(account).split(TASK_ROLE_PARTITION_PLACEHOLDER).join(partition);
|
|
4921
|
+
}
|
|
4922
|
+
function hasTaskRolePlaceholder(arn) {
|
|
4923
|
+
return arn.includes("${AWS::AccountId}") || arn.includes("${AWS::Partition}");
|
|
4924
|
+
}
|
|
4925
|
+
function sameStackRoleLogicalId(value, resources) {
|
|
4926
|
+
if (!value || typeof value !== "object") return void 0;
|
|
4893
4927
|
const obj = value;
|
|
4894
4928
|
let refLogicalId;
|
|
4895
4929
|
if ("Ref" in obj && typeof obj["Ref"] === "string") refLogicalId = obj["Ref"];
|
|
@@ -4900,16 +4934,48 @@ function resolveRoleArn(value, resources, subContext) {
|
|
|
4900
4934
|
if (attr === "" || attr === "Arn") refLogicalId = arg[0];
|
|
4901
4935
|
}
|
|
4902
4936
|
}
|
|
4937
|
+
if (refLogicalId === void 0) return void 0;
|
|
4938
|
+
return resources[refLogicalId]?.Type === "AWS::IAM::Role" ? refLogicalId : void 0;
|
|
4939
|
+
}
|
|
4940
|
+
function roleArnFromStateRecord(logicalId, role, subContext) {
|
|
4941
|
+
if (!subContext) return { reason: "no-state" };
|
|
4942
|
+
const record = subContext.resources[logicalId];
|
|
4943
|
+
if (!record) return { reason: "no-record" };
|
|
4944
|
+
const arn = record.attributes?.["Arn"];
|
|
4945
|
+
if (typeof arn === "string" && arn.length > 0) return { arn };
|
|
4946
|
+
const name = record.physicalId;
|
|
4947
|
+
if (typeof name !== "string" || name.length === 0) return { reason: "no-record" };
|
|
4948
|
+
if (name.startsWith("arn:")) return { arn: name };
|
|
4949
|
+
const rawPath = role.Properties?.["Path"];
|
|
4950
|
+
if (rawPath === void 0) return { arn: placeholderRoleArn(`/${name}`) };
|
|
4951
|
+
if (typeof rawPath !== "string" || !/^\/(?:.*\/)?$/.test(rawPath)) return { reason: "path-not-literal" };
|
|
4952
|
+
return { arn: placeholderRoleArn(`${rawPath}${name}`) };
|
|
4953
|
+
}
|
|
4954
|
+
function resolveRoleArn(value, resources, subContext) {
|
|
4955
|
+
if (value === void 0 || value === null) return {};
|
|
4956
|
+
if (typeof value === "string") return { arn: value };
|
|
4957
|
+
if (typeof value !== "object") return {};
|
|
4958
|
+
const obj = value;
|
|
4959
|
+
const refLogicalId = sameStackRoleLogicalId(value, resources);
|
|
4903
4960
|
if (refLogicalId !== void 0) {
|
|
4904
|
-
|
|
4905
|
-
return
|
|
4961
|
+
const fromState = roleArnFromStateRecord(refLogicalId, resources[refLogicalId], subContext);
|
|
4962
|
+
if ("arn" in fromState) return { arn: fromState.arn };
|
|
4963
|
+
return {
|
|
4964
|
+
arn: placeholderRoleArn(`/${refLogicalId}`),
|
|
4965
|
+
unresolved: {
|
|
4966
|
+
logicalId: refLogicalId,
|
|
4967
|
+
reason: fromState.reason
|
|
4968
|
+
}
|
|
4969
|
+
};
|
|
4906
4970
|
}
|
|
4971
|
+
if ("Ref" in obj || "Fn::GetAtt" in obj) return {};
|
|
4907
4972
|
if ("Fn::Join" in obj || "Fn::Sub" in obj) {
|
|
4908
|
-
if (!subContext) return
|
|
4973
|
+
if (!subContext) return {};
|
|
4909
4974
|
const sub = substituteAgainstState(value, subContext);
|
|
4910
|
-
if (sub.kind === "literal" && typeof sub.value === "string" && sub.value.length > 0) return sub.value;
|
|
4911
|
-
return;
|
|
4975
|
+
if (sub.kind === "literal" && typeof sub.value === "string" && sub.value.length > 0) return { arn: sub.value };
|
|
4976
|
+
return {};
|
|
4912
4977
|
}
|
|
4978
|
+
return {};
|
|
4913
4979
|
}
|
|
4914
4980
|
function pickString(value) {
|
|
4915
4981
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
@@ -5865,6 +5931,10 @@ async function localInvokeCommand(target, options, extraStateProviders) {
|
|
|
5865
5931
|
});
|
|
5866
5932
|
try {
|
|
5867
5933
|
await activateWorkloadAwsWiring(options);
|
|
5934
|
+
warnIfEmulateRoleViaUnused(options.emulateRoleVia, {
|
|
5935
|
+
roleFlag: "--assume-role",
|
|
5936
|
+
roleRequested: options.assumeRole !== void 0 && options.assumeRole !== false
|
|
5937
|
+
});
|
|
5868
5938
|
await applyRoleArnIfSet({
|
|
5869
5939
|
roleArn: options.roleArn,
|
|
5870
5940
|
region: options.region,
|
|
@@ -6368,7 +6438,8 @@ async function resolveLambdaContainerEnvWith(lambda, options, profileCredentials
|
|
|
6368
6438
|
roleArn: resolvedAssumeRoleArn,
|
|
6369
6439
|
region: stsRegion,
|
|
6370
6440
|
profile: options.profile,
|
|
6371
|
-
sessionNameSuffix: "invoke"
|
|
6441
|
+
sessionNameSuffix: "invoke",
|
|
6442
|
+
emulateRoleVia: options.emulateRoleVia
|
|
6372
6443
|
});
|
|
6373
6444
|
dockerEnv["AWS_ACCESS_KEY_ID"] = creds.accessKeyId;
|
|
6374
6445
|
dockerEnv["AWS_SECRET_ACCESS_KEY"] = creds.secretAccessKey;
|
|
@@ -6496,7 +6567,7 @@ function createLocalInvokeCommand(opts = {}) {
|
|
|
6496
6567
|
}
|
|
6497
6568
|
function addInvokeSpecificOptions(cmd) {
|
|
6498
6569
|
addAwsEndpointOptions(cmd);
|
|
6499
|
-
return cmd.addOption(new Option("-e, --event <file>", "JSON event payload file (default: {})")).addOption(new Option("--event-stdin", "Read event JSON from stdin").default(false)).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"LogicalId\":{\"KEY\":\"VALUE\"}, \"Parameters\": {...}})")).addOption(new Option("--no-pull", "Skip docker pull. Semantics differ by code path: ZIP Lambdas skip pulling the public Lambda base image; Container Lambdas on the local-build path are a no-op (docker build does not refresh the FROM cache by default); Container Lambdas on the ECR-pull fallback skip docker pull AND error if the image is not in the local cache (re-run without --no-pull or pre-pull manually).")).addOption(new Option("--no-build", "Skip docker build on the IMAGE local-build path (use the previously-built tag). Requires the deterministic tag to already be in the local registry; errors with an actionable message when missing. No-op for ZIP Lambdas and the IMAGE ECR-pull path. Compatible with --no-pull.")).addOption(new Option("--debug-port <port>", "Node --inspect-brk port (default: off)")).addOption(new Option("--container-host <host>", "Host IP the host uses to bind the RIE port to. Must be a numeric IP (Docker rejects hostnames here). Defaults to 127.0.0.1.").default("127.0.0.1")).addOption(new Option("--assume-role [arn]", "Assume the Lambda's deployed execution role and forward STS-issued temp credentials to the container so the handler runs with the deployed function's narrow permissions. Three forms: (1) `--assume-role <arn>` assumes the explicit ARN; (2) `--assume-role` (bare) auto-resolves the function's execution role ARN from state (requires an active state source); (3) `--no-assume-role` explicitly opts out. Off by default — when omitted, the developer's shell credentials are forwarded unchanged (SAM-compatible default). STS failures degrade to a warn + dev-creds fallback.")).addOption(new Option("--layer-role-arn <arn>", "Role to sts:AssumeRole before calling lambda:GetLayerVersion on every literal-ARN entry in Properties.Layers. Use only when the dev credentials cannot read the layer — typically cross-account layers. AWS-published public layers (e.g. Lambda Powertools) are readable from every account and need no role.")).addOption(new Option("--ecr-role-arn <arn>", "Role ARN to assume before authenticating against ECR for cross-account / centralized registries. Issues sts:AssumeRole via the default credential chain and uses the temporary credentials for ecr:GetAuthorizationToken + docker pull. Required when the caller does not have direct cross-account access to the target repository. Same-account / same-region pulls do not need this flag.")).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Read a deployed CloudFormation stack via ListStackResources and substitute Ref / Fn::ImportValue in env vars with the deployed physical IDs / exports. Use for CDK apps deployed via the upstream CDK CLI (`cdk deploy`). Bare form uses the resolved stack name; pass an explicit value when CFn stack name differs. Fn::GetAtt is warn-and-dropped in v1 (CFn ListStackResources does not return per-attribute values).")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-cfn-stack as the CFn client region.")).addOption(new Option("--response-file <path>", "Also write the raw Lambda response payload to this file. Lets a programmatic caller recover the response without parsing it out of stdout (where it interleaves with synth progress + streamed container logs). stdout output is unchanged."));
|
|
6570
|
+
return cmd.addOption(new Option("-e, --event <file>", "JSON event payload file (default: {})")).addOption(new Option("--event-stdin", "Read event JSON from stdin").default(false)).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"LogicalId\":{\"KEY\":\"VALUE\"}, \"Parameters\": {...}})")).addOption(new Option("--no-pull", "Skip docker pull. Semantics differ by code path: ZIP Lambdas skip pulling the public Lambda base image; Container Lambdas on the local-build path are a no-op (docker build does not refresh the FROM cache by default); Container Lambdas on the ECR-pull fallback skip docker pull AND error if the image is not in the local cache (re-run without --no-pull or pre-pull manually).")).addOption(new Option("--no-build", "Skip docker build on the IMAGE local-build path (use the previously-built tag). Requires the deterministic tag to already be in the local registry; errors with an actionable message when missing. No-op for ZIP Lambdas and the IMAGE ECR-pull path. Compatible with --no-pull.")).addOption(new Option("--debug-port <port>", "Node --inspect-brk port (default: off)")).addOption(new Option("--container-host <host>", "Host IP the host uses to bind the RIE port to. Must be a numeric IP (Docker rejects hostnames here). Defaults to 127.0.0.1.").default("127.0.0.1")).addOption(new Option("--assume-role [arn]", "Assume the Lambda's deployed execution role and forward STS-issued temp credentials to the container so the handler runs with the deployed function's narrow permissions. Three forms: (1) `--assume-role <arn>` assumes the explicit ARN; (2) `--assume-role` (bare) auto-resolves the function's execution role ARN from state (requires an active state source); (3) `--no-assume-role` explicitly opts out. Off by default — when omitted, the developer's shell credentials are forwarded unchanged (SAM-compatible default). STS failures degrade to a warn + dev-creds fallback.")).addOption(emulateRoleViaOption("--assume-role")).addOption(new Option("--layer-role-arn <arn>", "Role to sts:AssumeRole before calling lambda:GetLayerVersion on every literal-ARN entry in Properties.Layers. Use only when the dev credentials cannot read the layer — typically cross-account layers. AWS-published public layers (e.g. Lambda Powertools) are readable from every account and need no role.")).addOption(new Option("--ecr-role-arn <arn>", "Role ARN to assume before authenticating against ECR for cross-account / centralized registries. Issues sts:AssumeRole via the default credential chain and uses the temporary credentials for ecr:GetAuthorizationToken + docker pull. Required when the caller does not have direct cross-account access to the target repository. Same-account / same-region pulls do not need this flag.")).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Read a deployed CloudFormation stack via ListStackResources and substitute Ref / Fn::ImportValue in env vars with the deployed physical IDs / exports. Use for CDK apps deployed via the upstream CDK CLI (`cdk deploy`). Bare form uses the resolved stack name; pass an explicit value when CFn stack name differs. Fn::GetAtt is warn-and-dropped in v1 (CFn ListStackResources does not return per-attribute values).")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-cfn-stack as the CFn client region.")).addOption(new Option("--response-file <path>", "Also write the raw Lambda response payload to this file. Lets a programmatic caller recover the response without parsing it out of stdout (where it interleaves with synth progress + streamed container logs). stdout output is unchanged."));
|
|
6500
6571
|
}
|
|
6501
6572
|
|
|
6502
6573
|
//#endregion
|
|
@@ -11687,6 +11758,10 @@ async function localStartApiCommand(targets, options, extraStateProviders) {
|
|
|
11687
11758
|
if (normalizedAssumeRole === void 0) delete options.assumeRole;
|
|
11688
11759
|
else options.assumeRole = normalizedAssumeRole;
|
|
11689
11760
|
await activateWorkloadAwsWiring(options);
|
|
11761
|
+
warnIfEmulateRoleViaUnused(options.emulateRoleVia, {
|
|
11762
|
+
roleFlag: "--assume-role",
|
|
11763
|
+
roleRequested: normalizedAssumeRole !== void 0
|
|
11764
|
+
});
|
|
11690
11765
|
await applyRoleArnIfSet({
|
|
11691
11766
|
roleArn: options.roleArn,
|
|
11692
11767
|
region: options.region,
|
|
@@ -11792,6 +11867,7 @@ async function localStartApiCommand(targets, options, extraStateProviders) {
|
|
|
11792
11867
|
stacks: servedStacks,
|
|
11793
11868
|
overrides,
|
|
11794
11869
|
assumeRole: normalizedAssumeRole,
|
|
11870
|
+
...options.emulateRoleVia !== void 0 && { emulateRoleVia: options.emulateRoleVia },
|
|
11795
11871
|
containerHost: options.containerHost,
|
|
11796
11872
|
...debugPortBase !== void 0 && { debugPort: debugPortBase + i },
|
|
11797
11873
|
stsRegion: options.region ?? process.env["AWS_REGION"] ?? process.env["AWS_DEFAULT_REGION"],
|
|
@@ -12435,7 +12511,7 @@ async function buildContainerSpec(args) {
|
|
|
12435
12511
|
profile
|
|
12436
12512
|
});
|
|
12437
12513
|
if (roleArn) {
|
|
12438
|
-
const creds = await assumeLambdaExecutionRole(roleArn, containerRegion, profile);
|
|
12514
|
+
const creds = await assumeLambdaExecutionRole(roleArn, containerRegion, profile, args.emulateRoleVia);
|
|
12439
12515
|
dockerEnv["AWS_ACCESS_KEY_ID"] = creds.accessKeyId;
|
|
12440
12516
|
dockerEnv["AWS_SECRET_ACCESS_KEY"] = creds.secretAccessKey;
|
|
12441
12517
|
dockerEnv["AWS_SESSION_TOKEN"] = creds.sessionToken;
|
|
@@ -12752,12 +12828,13 @@ function forwardAwsEnv$2(env) {
|
|
|
12752
12828
|
}
|
|
12753
12829
|
return applyWorkloadEnvCredentials(env);
|
|
12754
12830
|
}
|
|
12755
|
-
async function assumeLambdaExecutionRole(roleArn, region, profile) {
|
|
12831
|
+
async function assumeLambdaExecutionRole(roleArn, region, profile, emulateRoleVia) {
|
|
12756
12832
|
return assumeRoleCredentials({
|
|
12757
12833
|
roleArn,
|
|
12758
12834
|
region,
|
|
12759
12835
|
profile,
|
|
12760
|
-
sessionNameSuffix: "start-api"
|
|
12836
|
+
sessionNameSuffix: "start-api",
|
|
12837
|
+
emulateRoleVia
|
|
12761
12838
|
});
|
|
12762
12839
|
}
|
|
12763
12840
|
function parsePerLambdaConcurrency(raw) {
|
|
@@ -13038,7 +13115,7 @@ function createLocalStartApiCommand(opts = {}) {
|
|
|
13038
13115
|
}
|
|
13039
13116
|
function addStartApiSpecificOptions(cmd) {
|
|
13040
13117
|
addAwsEndpointOptions(cmd);
|
|
13041
|
-
return cmd.addOption(new Option("--port <port>", "HTTP server port (default: auto-allocate)").default("0")).addOption(new Option("--host <host>", "Bind address").default("127.0.0.1")).addOption(new Option("--stack <name>", "Stack to start (single-stack apps auto-detect)")).addOption(new Option("--all-stacks", "Serve every stack's API in a multi-stack app (each API on its own port) instead of erroring out. Mutually exclusive with a positional target subset, --stack, and an explicit --from-cfn-stack <name>; the bare --from-cfn-stack flag stays compatible (binds each routed stack to its own CFn stack).").default(false)).addOption(new Option("--warm", "Pre-start one container per Lambda at server boot").default(false)).addOption(new Option("--per-lambda-concurrency <n>", "Pool size cap per Lambda (default 2, max 4)").default("2")).addOption(new Option("--no-pull", "Skip docker pull (cached image)")).addOption(new Option("--no-build", "Skip docker build on every container Lambda local-asset build (use the previously-built tag). Requires the deterministic tag to already be in the local registry; errors with an actionable message when missing. No-op for ZIP Lambdas and the IMAGE ECR-pull path. Compatible with --no-pull.")).addOption(new Option("--container-host <host>", "IP the host uses to bind/probe the RIE port (must be a numeric IP — `docker run -p <ip>:<port>:8080` rejects hostnames). Defaults to 127.0.0.1.").default("127.0.0.1")).addOption(new Option("--debug-port-base <port>", "Reserve a contiguous --debug-port range (one per Lambda)")).addOption(new Option("--debug-port <port>", "Alias of --debug-port-base for parity with `cdkl invoke --debug-port`. Reserves a contiguous --debug-port range (one per Lambda) starting at <port>.")).addOption(new Option("--ecr-role-arn <arn>", "Role ARN to assume before authenticating against ECR for cross-account / centralized registries on the container-Lambda ECR-pull fallback. Issues sts:AssumeRole via the default credential chain and uses the temporary credentials for ecr:GetAuthorizationToken + docker pull. Required when the caller does not have direct cross-account access to the target repository. Same-account / same-region pulls do not need this flag.")).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"LogicalId\":{\"KEY\":\"VALUE\"}, \"Parameters\": {...}})")).addOption(new Option("--assume-role <arn-or-pair>", "Assume the Lambda's execution role and forward STS-issued temp creds. Two forms: (1) `--assume-role <arn>` sets a single global default ARN used for every routed Lambda; (2) `--assume-role <LogicalId>=<arn>` (repeatable) is a per-Lambda override (wins over the global default and over --assume-role-auto for the named Lambda). Pair with --assume-role-auto to auto-resolve every other Lambda. Precedence: per-Lambda > (--assume-role-auto OR global default) > unset (developer creds passed through).").argParser((raw, prev) => parseAssumeRoleToken(raw, prev))).addOption(new Option("--assume-role-auto", "Auto-resolve EACH routed Lambda's own execution role per-Lambda (literal ARN / Fn::GetAtt against template / --from-cfn-stack state). Slower boot — one STS call per Lambda — but the right shape when each Lambda's deployed role differs. Mutually exclusive with `--assume-role <arn>` (global default); errors at boot. Compatible with `--assume-role <LogicalId>=<arn>` per-Lambda overrides — the map wins for named Lambdas, auto-resolve handles the rest.").default(false)).addOption(new Option("--watch", "Hot-reload: re-synth + re-discover routes when the CDK app's source changes (honors cdk.json watch.include/exclude; cdk.out, cdk.context.json, node_modules, .git are always excluded). Off by default; the server keeps the previous version serving when synth fails mid-reload.").default(false)).addOption(new Option("--stage <name>", "Select an API Gateway Stage by its 'StageName'. Default: the first Stage attached to each API. Drives event.stageVariables for both REST v1 and HTTP API v2. NOTE: For HTTP API v2 routes, requestContext.stage is always '$default' regardless of this flag (AWS-side limitation — HTTP API only exposes one stage to the integration event); only event.stageVariables is affected for v2 routes. For REST v1 routes the selected StageName is also threaded into requestContext.stage.")).addOption(new Option("--api <id>", "DEPRECATED — use the positional <targets...> argument instead. Accepts a SINGLE identifier; for a subset pass multiple positional targets. Same accepted forms (bare logical id, stack-qualified, Construct path, ancestor prefix). Will be removed in a future major release.")).addOption(new Option("--layer-role-arn <arn>", "Role to sts:AssumeRole before calling lambda:GetLayerVersion on every literal-ARN entry in Properties.Layers (issue #448). Use only when the dev credentials cannot read the layer — typically cross-account layers. AWS-published public layers (e.g. Lambda Powertools) are readable from every account and need no role.")).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Read a deployed CloudFormation stack via ListStackResources and substitute Ref / Fn::ImportValue in Lambda env vars with the deployed physical IDs / exports. Use for CDK apps deployed via the upstream CDK CLI (`cdk deploy`). Bare form uses the resolved stack name per routed stack; pass an explicit value when a single CFn stack should serve every routed stack. Fn::GetAtt is warn-and-dropped in v1 (CFn ListStackResources does not return per-attribute values).")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-cfn-stack as the CFn client region.")).addOption(new Option("--mtls-truststore <path>", `PEM-encoded CA bundle for client-certificate verification (mutual TLS). When set, the local server switches from HTTP to HTTPS and the TLS handshake rejects clients whose certificate doesn't chain to one of these CAs. Verified certs are surfaced on the Lambda event under requestContext.identity.clientCert (REST v1) / requestContext.authentication.clientCert (HTTP API v2). Must be set together with --mtls-cert + --mtls-key; partial flag sets are rejected. Generate a CA + server + client cert for local dev: openssl req -x509 -newkey rsa:2048 -nodes -keyout ca-key.pem -out ca.pem -subj "/CN=${getEmbedConfig().resourceNamePrefix}-ca" -days 365; openssl req -newkey rsa:2048 -nodes -keyout server-key.pem -out server-csr.pem -subj "/CN=localhost"; openssl x509 -req -in server-csr.pem -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -days 365; openssl req -newkey rsa:2048 -nodes -keyout client-key.pem -out client-csr.pem -subj "/CN=client"; openssl x509 -req -in client-csr.pem -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out client-cert.pem -days 365; curl --cacert ca.pem --cert client-cert.pem --key client-key.pem https://localhost:<port>/...`)).addOption(new Option("--mtls-cert <path>", "PEM-encoded server certificate for mutual TLS. Self-signed is fine for local dev. Must be set together with --mtls-truststore + --mtls-key.")).addOption(new Option("--mtls-key <path>", "PEM-encoded server private key matching --mtls-cert. Must be set together with --mtls-truststore + --mtls-cert.")).addOption(new Option("--strict-sigv4", "Opt-in: DENY AWS_IAM SigV4 requests that cannot be cryptographically verified (foreign access-key-id — e.g. a federated / Cognito Identity Pool / cross-account signer — OR no local AWS credentials configured) instead of the default warn-and-pass. DEFAULT off: cdk-local warn-and-passes unverifiable IAM requests with a placeholder principalId so local dev exercises app logic without reproducing an auth boundary it cannot fully emulate. OAC-fronted Function URLs always warn-and-pass regardless.").default(false));
|
|
13118
|
+
return cmd.addOption(new Option("--port <port>", "HTTP server port (default: auto-allocate)").default("0")).addOption(new Option("--host <host>", "Bind address").default("127.0.0.1")).addOption(new Option("--stack <name>", "Stack to start (single-stack apps auto-detect)")).addOption(new Option("--all-stacks", "Serve every stack's API in a multi-stack app (each API on its own port) instead of erroring out. Mutually exclusive with a positional target subset, --stack, and an explicit --from-cfn-stack <name>; the bare --from-cfn-stack flag stays compatible (binds each routed stack to its own CFn stack).").default(false)).addOption(new Option("--warm", "Pre-start one container per Lambda at server boot").default(false)).addOption(new Option("--per-lambda-concurrency <n>", "Pool size cap per Lambda (default 2, max 4)").default("2")).addOption(new Option("--no-pull", "Skip docker pull (cached image)")).addOption(new Option("--no-build", "Skip docker build on every container Lambda local-asset build (use the previously-built tag). Requires the deterministic tag to already be in the local registry; errors with an actionable message when missing. No-op for ZIP Lambdas and the IMAGE ECR-pull path. Compatible with --no-pull.")).addOption(new Option("--container-host <host>", "IP the host uses to bind/probe the RIE port (must be a numeric IP — `docker run -p <ip>:<port>:8080` rejects hostnames). Defaults to 127.0.0.1.").default("127.0.0.1")).addOption(new Option("--debug-port-base <port>", "Reserve a contiguous --debug-port range (one per Lambda)")).addOption(new Option("--debug-port <port>", "Alias of --debug-port-base for parity with `cdkl invoke --debug-port`. Reserves a contiguous --debug-port range (one per Lambda) starting at <port>.")).addOption(new Option("--ecr-role-arn <arn>", "Role ARN to assume before authenticating against ECR for cross-account / centralized registries on the container-Lambda ECR-pull fallback. Issues sts:AssumeRole via the default credential chain and uses the temporary credentials for ecr:GetAuthorizationToken + docker pull. Required when the caller does not have direct cross-account access to the target repository. Same-account / same-region pulls do not need this flag.")).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"LogicalId\":{\"KEY\":\"VALUE\"}, \"Parameters\": {...}})")).addOption(new Option("--assume-role <arn-or-pair>", "Assume the Lambda's execution role and forward STS-issued temp creds. Two forms: (1) `--assume-role <arn>` sets a single global default ARN used for every routed Lambda; (2) `--assume-role <LogicalId>=<arn>` (repeatable) is a per-Lambda override (wins over the global default and over --assume-role-auto for the named Lambda). Pair with --assume-role-auto to auto-resolve every other Lambda. Precedence: per-Lambda > (--assume-role-auto OR global default) > unset (developer creds passed through).").argParser((raw, prev) => parseAssumeRoleToken(raw, prev))).addOption(new Option("--assume-role-auto", "Auto-resolve EACH routed Lambda's own execution role per-Lambda (literal ARN / Fn::GetAtt against template / --from-cfn-stack state). Slower boot — one STS call per Lambda — but the right shape when each Lambda's deployed role differs. Mutually exclusive with `--assume-role <arn>` (global default); errors at boot. Compatible with `--assume-role <LogicalId>=<arn>` per-Lambda overrides — the map wins for named Lambdas, auto-resolve handles the rest.").default(false)).addOption(emulateRoleViaOption("--assume-role")).addOption(new Option("--watch", "Hot-reload: re-synth + re-discover routes when the CDK app's source changes (honors cdk.json watch.include/exclude; cdk.out, cdk.context.json, node_modules, .git are always excluded). Off by default; the server keeps the previous version serving when synth fails mid-reload.").default(false)).addOption(new Option("--stage <name>", "Select an API Gateway Stage by its 'StageName'. Default: the first Stage attached to each API. Drives event.stageVariables for both REST v1 and HTTP API v2. NOTE: For HTTP API v2 routes, requestContext.stage is always '$default' regardless of this flag (AWS-side limitation — HTTP API only exposes one stage to the integration event); only event.stageVariables is affected for v2 routes. For REST v1 routes the selected StageName is also threaded into requestContext.stage.")).addOption(new Option("--api <id>", "DEPRECATED — use the positional <targets...> argument instead. Accepts a SINGLE identifier; for a subset pass multiple positional targets. Same accepted forms (bare logical id, stack-qualified, Construct path, ancestor prefix). Will be removed in a future major release.")).addOption(new Option("--layer-role-arn <arn>", "Role to sts:AssumeRole before calling lambda:GetLayerVersion on every literal-ARN entry in Properties.Layers (issue #448). Use only when the dev credentials cannot read the layer — typically cross-account layers. AWS-published public layers (e.g. Lambda Powertools) are readable from every account and need no role.")).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Read a deployed CloudFormation stack via ListStackResources and substitute Ref / Fn::ImportValue in Lambda env vars with the deployed physical IDs / exports. Use for CDK apps deployed via the upstream CDK CLI (`cdk deploy`). Bare form uses the resolved stack name per routed stack; pass an explicit value when a single CFn stack should serve every routed stack. Fn::GetAtt is warn-and-dropped in v1 (CFn ListStackResources does not return per-attribute values).")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-cfn-stack as the CFn client region.")).addOption(new Option("--mtls-truststore <path>", `PEM-encoded CA bundle for client-certificate verification (mutual TLS). When set, the local server switches from HTTP to HTTPS and the TLS handshake rejects clients whose certificate doesn't chain to one of these CAs. Verified certs are surfaced on the Lambda event under requestContext.identity.clientCert (REST v1) / requestContext.authentication.clientCert (HTTP API v2). Must be set together with --mtls-cert + --mtls-key; partial flag sets are rejected. Generate a CA + server + client cert for local dev: openssl req -x509 -newkey rsa:2048 -nodes -keyout ca-key.pem -out ca.pem -subj "/CN=${getEmbedConfig().resourceNamePrefix}-ca" -days 365; openssl req -newkey rsa:2048 -nodes -keyout server-key.pem -out server-csr.pem -subj "/CN=localhost"; openssl x509 -req -in server-csr.pem -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -days 365; openssl req -newkey rsa:2048 -nodes -keyout client-key.pem -out client-csr.pem -subj "/CN=client"; openssl x509 -req -in client-csr.pem -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out client-cert.pem -days 365; curl --cacert ca.pem --cert client-cert.pem --key client-key.pem https://localhost:<port>/...`)).addOption(new Option("--mtls-cert <path>", "PEM-encoded server certificate for mutual TLS. Self-signed is fine for local dev. Must be set together with --mtls-truststore + --mtls-key.")).addOption(new Option("--mtls-key <path>", "PEM-encoded server private key matching --mtls-cert. Must be set together with --mtls-truststore + --mtls-cert.")).addOption(new Option("--strict-sigv4", "Opt-in: DENY AWS_IAM SigV4 requests that cannot be cryptographically verified (foreign access-key-id — e.g. a federated / Cognito Identity Pool / cross-account signer — OR no local AWS credentials configured) instead of the default warn-and-pass. DEFAULT off: cdk-local warn-and-passes unverifiable IAM requests with a placeholder principalId so local dev exercises app logic without reproducing an auth boundary it cannot fully emulate. OAC-fronted Function URLs always warn-and-pass regardless.").default(false));
|
|
13042
13119
|
}
|
|
13043
13120
|
|
|
13044
13121
|
//#endregion
|
|
@@ -13815,6 +13892,10 @@ async function localInvokeAgentCoreCommand(target, options, extraStateProviders)
|
|
|
13815
13892
|
});
|
|
13816
13893
|
try {
|
|
13817
13894
|
await activateWorkloadAwsWiring(options);
|
|
13895
|
+
warnIfEmulateRoleViaUnused(options.emulateRoleVia, {
|
|
13896
|
+
roleFlag: "--assume-role",
|
|
13897
|
+
roleRequested: options.assumeRole !== void 0 && options.assumeRole !== false
|
|
13898
|
+
});
|
|
13818
13899
|
await applyRoleArnIfSet({
|
|
13819
13900
|
roleArn: options.roleArn,
|
|
13820
13901
|
region: options.region,
|
|
@@ -14076,7 +14157,7 @@ async function resolveHostCredentialsForSigV4(options, resolved, loaded, region,
|
|
|
14076
14157
|
const logger = getLogger();
|
|
14077
14158
|
const assumeRoleArn = await resolveAssumeRoleArn(options, resolved, loaded, stateProvider);
|
|
14078
14159
|
if (assumeRoleArn) try {
|
|
14079
|
-
return await assumeAgentCoreExecutionRole(assumeRoleArn, region, options.profile);
|
|
14160
|
+
return await assumeAgentCoreExecutionRole(assumeRoleArn, region, options.profile, options.emulateRoleVia);
|
|
14080
14161
|
} catch (err) {
|
|
14081
14162
|
const sigv4Detail = assumeRoleDetail(err, "STS AssumeRole (--sigv4 signing)");
|
|
14082
14163
|
logger.warn(`--assume-role: STS AssumeRole(${flattenToOneLine(assumeRoleArn)}) failed for --sigv4 signing: ${sigv4Detail}. Falling back to ${options.profile ? `--profile ${displayUntrustedValue(options.profile)}` : "shell credentials"}.`);
|
|
@@ -14182,7 +14263,7 @@ async function resolveAgentCoreCodeImageFromS3(resolved, code, s3Source, options
|
|
|
14182
14263
|
const assumeRoleArn = await resolveAssumeRoleArn(options, resolved, loaded, stateProvider);
|
|
14183
14264
|
let credentials;
|
|
14184
14265
|
if (assumeRoleArn) try {
|
|
14185
|
-
credentials = await assumeAgentCoreExecutionRole(assumeRoleArn, region, options.profile);
|
|
14266
|
+
credentials = await assumeAgentCoreExecutionRole(assumeRoleArn, region, options.profile, options.emulateRoleVia);
|
|
14186
14267
|
} catch (err) {
|
|
14187
14268
|
const bundleDetail = assumeRoleDetail(err, "STS AssumeRole (fromS3 bundle download)");
|
|
14188
14269
|
logger.warn(`--assume-role: STS AssumeRole(${flattenToOneLine(assumeRoleArn)}) failed for the fromS3 bundle download: ${bundleDetail}. Falling back to ${options.profile ? `--profile ${displayUntrustedValue(options.profile)}` : "the default credentials"}.`);
|
|
@@ -14277,6 +14358,7 @@ async function buildContainerEnvWith(resolved, options, profileCredentials, prof
|
|
|
14277
14358
|
const stackRegion = options.stackRegion ?? resolved.stack.region;
|
|
14278
14359
|
await applyAgentCoreCredentialEnv(dockerEnv, {
|
|
14279
14360
|
...assumeRoleArn !== void 0 && { assumeRoleArn },
|
|
14361
|
+
...options.emulateRoleVia !== void 0 && { emulateRoleVia: options.emulateRoleVia },
|
|
14280
14362
|
...options.region !== void 0 && { region: options.region },
|
|
14281
14363
|
...stackRegion !== void 0 && { stackRegion },
|
|
14282
14364
|
...loaded?.region !== void 0 && { stateRegion: loaded.region },
|
|
@@ -14373,7 +14455,7 @@ async function applyAgentCoreCredentialEnv(dockerEnv, args) {
|
|
|
14373
14455
|
if (args.assumeRoleArn) {
|
|
14374
14456
|
const stsRegion = containerRegion;
|
|
14375
14457
|
try {
|
|
14376
|
-
const creds = await assumeAgentCoreExecutionRole(args.assumeRoleArn, stsRegion, args.profile);
|
|
14458
|
+
const creds = await assumeAgentCoreExecutionRole(args.assumeRoleArn, stsRegion, args.profile, args.emulateRoleVia);
|
|
14377
14459
|
dockerEnv["AWS_ACCESS_KEY_ID"] = creds.accessKeyId;
|
|
14378
14460
|
dockerEnv["AWS_SECRET_ACCESS_KEY"] = creds.secretAccessKey;
|
|
14379
14461
|
dockerEnv["AWS_SESSION_TOKEN"] = creds.sessionToken;
|
|
@@ -14502,7 +14584,7 @@ function forwardAwsEnv$1(env) {
|
|
|
14502
14584
|
}
|
|
14503
14585
|
return applyWorkloadEnvCredentials(env);
|
|
14504
14586
|
}
|
|
14505
|
-
async function assumeAgentCoreExecutionRole(roleArn, region, profile) {
|
|
14587
|
+
async function assumeAgentCoreExecutionRole(roleArn, region, profile, emulateRoleVia) {
|
|
14506
14588
|
if (!isIamRoleArn(roleArn)) throw new AssumeRoleFailure(refusedRoleArnMessage(roleArn), `the role ARN is not well-formed: ${describeRejectedRoleArn(roleArn)}`);
|
|
14507
14589
|
const { STSClient, AssumeRoleCommand } = await import("@aws-sdk/client-sts");
|
|
14508
14590
|
const sts = new STSClient(workloadStsClientConfig({
|
|
@@ -14510,11 +14592,26 @@ async function assumeAgentCoreExecutionRole(roleArn, region, profile) {
|
|
|
14510
14592
|
profile
|
|
14511
14593
|
}));
|
|
14512
14594
|
try {
|
|
14513
|
-
|
|
14514
|
-
|
|
14515
|
-
|
|
14516
|
-
|
|
14517
|
-
|
|
14595
|
+
let response;
|
|
14596
|
+
try {
|
|
14597
|
+
response = await sts.send(new AssumeRoleCommand({
|
|
14598
|
+
RoleArn: roleArn,
|
|
14599
|
+
RoleSessionName: `${getEmbedConfig().resourceNamePrefix}-invoke-agentcore-${Date.now()}`,
|
|
14600
|
+
DurationSeconds: 3600
|
|
14601
|
+
}));
|
|
14602
|
+
} catch (err) {
|
|
14603
|
+
const emulated = await emulateRoleAfterDeniedAssume(err, {
|
|
14604
|
+
roleArn,
|
|
14605
|
+
region,
|
|
14606
|
+
profile,
|
|
14607
|
+
emulateRoleVia,
|
|
14608
|
+
flag: "--assume-role",
|
|
14609
|
+
sessionNameSuffix: "invoke-agentcore"
|
|
14610
|
+
});
|
|
14611
|
+
if (emulated !== void 0) return emulated;
|
|
14612
|
+
throw err;
|
|
14613
|
+
}
|
|
14614
|
+
const creds = response.Credentials;
|
|
14518
14615
|
if (!creds?.AccessKeyId || !creds.SecretAccessKey || !creds.SessionToken) throw new AssumeRoleFailure(`AssumeRole(${flattenToOneLine(roleArn)}) returned no usable credentials.`, "the response carried no usable credentials");
|
|
14519
14616
|
return {
|
|
14520
14617
|
accessKeyId: creds.AccessKeyId,
|
|
@@ -14846,7 +14943,7 @@ function createLocalInvokeAgentCoreCommand(opts = {}) {
|
|
|
14846
14943
|
}
|
|
14847
14944
|
function addInvokeAgentCoreSpecificOptions(cmd) {
|
|
14848
14945
|
addAwsEndpointOptions(cmd);
|
|
14849
|
-
return cmd.addOption(new Option("-e, --event <file>", "JSON event payload file (default: {})")).addOption(new Option("--event-stdin", "Read event JSON from stdin").default(false)).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"LogicalId\":{\"KEY\":\"VALUE\"}, \"Parameters\": {...}})")).addOption(new Option("--session-id <id>", "AgentCore runtime session id header value (default: a random UUID)")).addOption(new Option("--ws", "Stream over the HTTP-protocol agent's bidirectional /ws WebSocket endpoint (on 8080) instead of POST /invocations: send --event as the first frame and print every received frame to stdout until the agent closes. When stdin is a TTY, additionally reads stdin lines as follow-up text frames (multi-turn REPL; Ctrl-D to end). When stdin is piped / redirected / non-TTY (CI), only the initial --event frame is sent (one-shot). Force one-shot in a TTY with `cdkl ... --ws </dev/null`. Ignored for an MCP runtime.").default(false)).addOption(new Option("--bearer-token <jwt>", "Bearer JWT this command SUPPLIES (the supplier role) when the runtime declares a customJwtAuthorizer — `cdkl invoke-agentcore` is the local-dev client making the outbound call, so it always presents this token to its own invocation. Verified against the runtime's OIDC discovery URL (signature / issuer / expiry / audience) before the container starts, then forwarded to /invocations as Authorization: Bearer <jwt>. Contrast with `cdkl start-alb --bearer-token`, where the role is reversed — the ALB front-door RECEIVES inbound requests and injects this token only as a default when an inbound request has none (default-when-missing).")).addOption(new Option("--no-verify-auth", "Skip inbound JWT verification even when the runtime declares a customJwtAuthorizer (local-dev escape hatch). A --bearer-token, if given, is still forwarded.")).addOption(new Option("--sigv4", "Sign the /invocations POST with AWS SigV4 (service bedrock-agentcore) using the resolved credentials, matching the cloud default when the runtime declares no customJwtAuthorizer. Opt-in: default unsigned. Mutually exclusive with --bearer-token; ignored on a JWT-protected runtime.").default(false)).addOption(new Option("--platform <platform>", "docker --platform for the agent container (linux/amd64 or linux/arm64). Defaults to linux/arm64 because the cloud AgentCore Runtime requires arm64. Override to linux/amd64 only when iterating against an amd64 dev container locally; note the image will not run on the cloud runtime as-is.").choices(["linux/amd64", "linux/arm64"]).default("linux/arm64")).addOption(new Option("--no-pull", "Skip docker pull (use cached image) — no-op for the local-build path")).addOption(new Option("--no-build", "Skip docker build on the local-asset path (use the previously-built tag). No-op for the ECR / registry pull paths.")).addOption(new Option("--container-host <host>", "Host IP the host uses to bind the agent port to. Must be a numeric IP (Docker rejects hostnames here). Defaults to 127.0.0.1.").default("127.0.0.1")).addOption(new Option("--timeout <ms>", "Per-request timeout in milliseconds. Applied to POST /invocations, POST /mcp, and the /ws open-to-close window. Raise this for long-running agent calls that exceed the default.").default(12e4).argParser(parseTimeoutMs)).addOption(new Option("--assume-role [arn]", "Assume the runtime's execution role and forward STS-issued temp credentials to the container so the agent runs with the deployed role. Three forms: (1) `--assume-role <arn>` assumes the explicit ARN; (2) `--assume-role` (bare) uses the runtime's RoleArn when it is a literal ARN; (3) `--no-assume-role` opts out. Off by default — the developer's shell credentials are forwarded unchanged.")).addOption(new Option("--ecr-role-arn <arn>", "Role ARN to assume before authenticating against ECR for cross-account / centralized registries. Same-account / same-region pulls do not need this flag.")).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Read a deployed CloudFormation stack via ListStackResources and substitute Ref / Fn::ImportValue in env vars with the deployed physical IDs / exports. Bare form uses the resolved stack name; pass an explicit value when the CFn stack name differs.")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-cfn-stack as the CFn client region.")).addOption(new Option("--watch", "Re-synth and reload the agent container on CDK source changes. Only meaningful with the long-running --ws session path; single-shot POST /invocations, MCP, and A2A invocations run once and exit, so --watch is logged as a no-op WARN for them and the single shot proceeds. The active /ws socket is closed cleanly on every reload firing so the next session connects to the rebuilt container — the honest local-dev semantic.").default(false));
|
|
14946
|
+
return cmd.addOption(new Option("-e, --event <file>", "JSON event payload file (default: {})")).addOption(new Option("--event-stdin", "Read event JSON from stdin").default(false)).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"LogicalId\":{\"KEY\":\"VALUE\"}, \"Parameters\": {...}})")).addOption(new Option("--session-id <id>", "AgentCore runtime session id header value (default: a random UUID)")).addOption(new Option("--ws", "Stream over the HTTP-protocol agent's bidirectional /ws WebSocket endpoint (on 8080) instead of POST /invocations: send --event as the first frame and print every received frame to stdout until the agent closes. When stdin is a TTY, additionally reads stdin lines as follow-up text frames (multi-turn REPL; Ctrl-D to end). When stdin is piped / redirected / non-TTY (CI), only the initial --event frame is sent (one-shot). Force one-shot in a TTY with `cdkl ... --ws </dev/null`. Ignored for an MCP runtime.").default(false)).addOption(new Option("--bearer-token <jwt>", "Bearer JWT this command SUPPLIES (the supplier role) when the runtime declares a customJwtAuthorizer — `cdkl invoke-agentcore` is the local-dev client making the outbound call, so it always presents this token to its own invocation. Verified against the runtime's OIDC discovery URL (signature / issuer / expiry / audience) before the container starts, then forwarded to /invocations as Authorization: Bearer <jwt>. Contrast with `cdkl start-alb --bearer-token`, where the role is reversed — the ALB front-door RECEIVES inbound requests and injects this token only as a default when an inbound request has none (default-when-missing).")).addOption(new Option("--no-verify-auth", "Skip inbound JWT verification even when the runtime declares a customJwtAuthorizer (local-dev escape hatch). A --bearer-token, if given, is still forwarded.")).addOption(new Option("--sigv4", "Sign the /invocations POST with AWS SigV4 (service bedrock-agentcore) using the resolved credentials, matching the cloud default when the runtime declares no customJwtAuthorizer. Opt-in: default unsigned. Mutually exclusive with --bearer-token; ignored on a JWT-protected runtime.").default(false)).addOption(new Option("--platform <platform>", "docker --platform for the agent container (linux/amd64 or linux/arm64). Defaults to linux/arm64 because the cloud AgentCore Runtime requires arm64. Override to linux/amd64 only when iterating against an amd64 dev container locally; note the image will not run on the cloud runtime as-is.").choices(["linux/amd64", "linux/arm64"]).default("linux/arm64")).addOption(new Option("--no-pull", "Skip docker pull (use cached image) — no-op for the local-build path")).addOption(new Option("--no-build", "Skip docker build on the local-asset path (use the previously-built tag). No-op for the ECR / registry pull paths.")).addOption(new Option("--container-host <host>", "Host IP the host uses to bind the agent port to. Must be a numeric IP (Docker rejects hostnames here). Defaults to 127.0.0.1.").default("127.0.0.1")).addOption(new Option("--timeout <ms>", "Per-request timeout in milliseconds. Applied to POST /invocations, POST /mcp, and the /ws open-to-close window. Raise this for long-running agent calls that exceed the default.").default(12e4).argParser(parseTimeoutMs)).addOption(new Option("--assume-role [arn]", "Assume the runtime's execution role and forward STS-issued temp credentials to the container so the agent runs with the deployed role. Three forms: (1) `--assume-role <arn>` assumes the explicit ARN; (2) `--assume-role` (bare) uses the runtime's RoleArn when it is a literal ARN; (3) `--no-assume-role` opts out. Off by default — the developer's shell credentials are forwarded unchanged.")).addOption(emulateRoleViaOption("--assume-role")).addOption(new Option("--ecr-role-arn <arn>", "Role ARN to assume before authenticating against ECR for cross-account / centralized registries. Same-account / same-region pulls do not need this flag.")).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Read a deployed CloudFormation stack via ListStackResources and substitute Ref / Fn::ImportValue in env vars with the deployed physical IDs / exports. Bare form uses the resolved stack name; pass an explicit value when the CFn stack name differs.")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-cfn-stack as the CFn client region.")).addOption(new Option("--watch", "Re-synth and reload the agent container on CDK source changes. Only meaningful with the long-running --ws session path; single-shot POST /invocations, MCP, and A2A invocations run once and exit, so --watch is logged as a no-op WARN for them and the single shot proceeds. The active /ws socket is closed cleanly on every reload firing so the next session connects to the rebuilt container — the honest local-dev semantic.").default(false));
|
|
14850
14947
|
}
|
|
14851
14948
|
|
|
14852
14949
|
//#endregion
|
|
@@ -16942,7 +17039,7 @@ async function softReloadReplica(args) {
|
|
|
16942
17039
|
const defaultDockerInspectWorkdirImpl = async (containerId) => {
|
|
16943
17040
|
const { execFile } = await import("node:child_process");
|
|
16944
17041
|
const { promisify } = await import("node:util");
|
|
16945
|
-
const { getDockerCmd } = await import("./docker-cmd-
|
|
17042
|
+
const { getDockerCmd } = await import("./docker-cmd-BnW-0c0e.js").then((n) => n.t);
|
|
16946
17043
|
const { stdout } = await promisify(execFile)(getDockerCmd(), [
|
|
16947
17044
|
"inspect",
|
|
16948
17045
|
"--format",
|
|
@@ -16955,7 +17052,7 @@ let dockerInspectWorkdirImpl = defaultDockerInspectWorkdirImpl;
|
|
|
16955
17052
|
const defaultDockerCpImpl = async (src, dst) => {
|
|
16956
17053
|
const { execFile } = await import("node:child_process");
|
|
16957
17054
|
const { promisify } = await import("node:util");
|
|
16958
|
-
const { getDockerCmd } = await import("./docker-cmd-
|
|
17055
|
+
const { getDockerCmd } = await import("./docker-cmd-BnW-0c0e.js").then((n) => n.t);
|
|
16959
17056
|
await promisify(execFile)(getDockerCmd(), [
|
|
16960
17057
|
"cp",
|
|
16961
17058
|
src,
|
|
@@ -16966,19 +17063,19 @@ let dockerCpImpl = defaultDockerCpImpl;
|
|
|
16966
17063
|
const defaultDockerStopImpl = async (containerId) => {
|
|
16967
17064
|
const { execFile } = await import("node:child_process");
|
|
16968
17065
|
const { promisify } = await import("node:util");
|
|
16969
|
-
const { getDockerCmd } = await import("./docker-cmd-
|
|
17066
|
+
const { getDockerCmd } = await import("./docker-cmd-BnW-0c0e.js").then((n) => n.t);
|
|
16970
17067
|
await promisify(execFile)(getDockerCmd(), ["stop", containerId]);
|
|
16971
17068
|
};
|
|
16972
17069
|
const defaultDockerStartImpl = async (containerId, opts = {}) => {
|
|
16973
17070
|
const { execFile } = await import("node:child_process");
|
|
16974
17071
|
const { promisify } = await import("node:util");
|
|
16975
|
-
const { getDockerCmd } = await import("./docker-cmd-
|
|
17072
|
+
const { getDockerCmd } = await import("./docker-cmd-BnW-0c0e.js").then((n) => n.t);
|
|
16976
17073
|
await promisify(execFile)(getDockerCmd(), ["start", containerId]);
|
|
16977
17074
|
if (opts.joinedForwarder) return;
|
|
16978
|
-
const { getActiveWorkloadAwsWiring } = await import("./workload-identity-
|
|
17075
|
+
const { getActiveWorkloadAwsWiring } = await import("./workload-identity-Blv2g1Jp.js").then((n) => n.B);
|
|
16979
17076
|
const wiring = getActiveWorkloadAwsWiring();
|
|
16980
17077
|
if (wiring) {
|
|
16981
|
-
const { attachLoopbackForwarder } = await import("./docker-runner-
|
|
17078
|
+
const { attachLoopbackForwarder } = await import("./docker-runner-DjcP2syq.js").then((n) => n.o);
|
|
16982
17079
|
await attachLoopbackForwarder(containerId, wiring);
|
|
16983
17080
|
}
|
|
16984
17081
|
};
|
|
@@ -17048,7 +17145,7 @@ async function attachToSharedNetwork(plan, withAliases) {
|
|
|
17048
17145
|
const defaultDockerNetworkConnectImpl = async (networkName, containerId, opts) => {
|
|
17049
17146
|
const { execFile } = await import("node:child_process");
|
|
17050
17147
|
const { promisify } = await import("node:util");
|
|
17051
|
-
const { getDockerCmd } = await import("./docker-cmd-
|
|
17148
|
+
const { getDockerCmd } = await import("./docker-cmd-BnW-0c0e.js").then((n) => n.t);
|
|
17052
17149
|
const args = ["network", "connect"];
|
|
17053
17150
|
if (opts.ip) args.push("--ip", opts.ip);
|
|
17054
17151
|
for (const a of opts.aliases) args.push("--alias", a);
|
|
@@ -17059,7 +17156,7 @@ let dockerNetworkConnectImpl = defaultDockerNetworkConnectImpl;
|
|
|
17059
17156
|
const defaultDockerInspectPublishesHostPortsImpl = async (containerId) => {
|
|
17060
17157
|
const { execFile } = await import("node:child_process");
|
|
17061
17158
|
const { promisify } = await import("node:util");
|
|
17062
|
-
const { getDockerCmd } = await import("./docker-cmd-
|
|
17159
|
+
const { getDockerCmd } = await import("./docker-cmd-BnW-0c0e.js").then((n) => n.t);
|
|
17063
17160
|
const { stdout } = await promisify(execFile)(getDockerCmd(), [
|
|
17064
17161
|
"inspect",
|
|
17065
17162
|
"--format",
|
|
@@ -17098,7 +17195,7 @@ async function disconnectOldFromSharedNetwork(oldInstance, opts = {}) {
|
|
|
17098
17195
|
const defaultDockerNetworkDisconnectImpl = async (networkName, containerId) => {
|
|
17099
17196
|
const { execFile } = await import("node:child_process");
|
|
17100
17197
|
const { promisify } = await import("node:util");
|
|
17101
|
-
const { getDockerCmd } = await import("./docker-cmd-
|
|
17198
|
+
const { getDockerCmd } = await import("./docker-cmd-BnW-0c0e.js").then((n) => n.t);
|
|
17102
17199
|
await promisify(execFile)(getDockerCmd(), [
|
|
17103
17200
|
"network",
|
|
17104
17201
|
"disconnect",
|
|
@@ -17189,7 +17286,7 @@ const LISTEN_PROBE_SCRIPT = [
|
|
|
17189
17286
|
async function dockerExecListenProbe(containerId, port, timeoutMs = 1e4) {
|
|
17190
17287
|
const { execFile } = await import("node:child_process");
|
|
17191
17288
|
const { promisify } = await import("node:util");
|
|
17192
|
-
const { getDockerCmd } = await import("./docker-cmd-
|
|
17289
|
+
const { getDockerCmd } = await import("./docker-cmd-BnW-0c0e.js").then((n) => n.t);
|
|
17193
17290
|
try {
|
|
17194
17291
|
await promisify(execFile)(getDockerCmd(), [
|
|
17195
17292
|
"exec",
|
|
@@ -17343,7 +17440,7 @@ function pickEssentialContainerId(instance, service) {
|
|
|
17343
17440
|
const defaultWaitForExitImpl = async (containerId) => {
|
|
17344
17441
|
const { execFile } = await import("node:child_process");
|
|
17345
17442
|
const { promisify } = await import("node:util");
|
|
17346
|
-
const { getDockerCmd } = await import("./docker-cmd-
|
|
17443
|
+
const { getDockerCmd } = await import("./docker-cmd-BnW-0c0e.js").then((n) => n.t);
|
|
17347
17444
|
const { stdout } = await promisify(execFile)(getDockerCmd(), ["wait", containerId], { maxBuffer: 1024 * 1024 });
|
|
17348
17445
|
const code = parseInt(stdout.trim(), 10);
|
|
17349
17446
|
return Number.isFinite(code) ? code : -1;
|
|
@@ -17353,7 +17450,7 @@ const EXIT_LOG_TAIL_LINES = 50;
|
|
|
17353
17450
|
const defaultReadContainerLogsImpl = async (containerId) => {
|
|
17354
17451
|
const { execFile } = await import("node:child_process");
|
|
17355
17452
|
const { promisify } = await import("node:util");
|
|
17356
|
-
const { getDockerCmd } = await import("./docker-cmd-
|
|
17453
|
+
const { getDockerCmd } = await import("./docker-cmd-BnW-0c0e.js").then((n) => n.t);
|
|
17357
17454
|
const { stdout, stderr } = await promisify(execFile)(getDockerCmd(), [
|
|
17358
17455
|
"logs",
|
|
17359
17456
|
"--tail",
|
|
@@ -19552,6 +19649,10 @@ async function runEcsServiceEmulator(targets, options, strategy, extraStateProvi
|
|
|
19552
19649
|
}, (err) => getLogger().warn(`service cleanup failed: ${err instanceof Error ? err.message : String(err)}`));
|
|
19553
19650
|
try {
|
|
19554
19651
|
await activateWorkloadAwsWiring(options);
|
|
19652
|
+
warnIfEmulateRoleViaUnused(options.emulateRoleVia, {
|
|
19653
|
+
roleFlag: "--assume-role",
|
|
19654
|
+
roleRequested: isRoleFlagRequested(options.assumeRole ?? options.assumeTaskRole)
|
|
19655
|
+
});
|
|
19555
19656
|
await applyRoleArnIfSet({
|
|
19556
19657
|
roleArn: options.roleArn,
|
|
19557
19658
|
region: options.region,
|
|
@@ -19963,11 +20064,12 @@ async function resolveServiceAndRunnerOpts(boot, stacks, options, discovery, ski
|
|
|
19963
20064
|
let resolvedRoleArn;
|
|
19964
20065
|
if (effectiveAssumeRole === true) {
|
|
19965
20066
|
if (!service.task.taskRoleArn) throw new LocalStartServiceError(`--assume-role passed without an ARN but service ${displayIdent(service.serviceLogicalId)} has no resolvable TaskRoleArn. Pass the ARN explicitly: --assume-role <arn>`);
|
|
20067
|
+
warnIfTaskRoleIsLogicalId(service.task, stateProvider, imageContext);
|
|
19966
20068
|
resolvedRoleArn = await resolveTaskRoleArnForOptions$1(service.task.taskRoleArn, options);
|
|
19967
|
-
assumedCredentials = await assumeTaskRole$1(resolvedRoleArn, options.region, options.profile);
|
|
20069
|
+
assumedCredentials = await assumeTaskRole$1(resolvedRoleArn, options.region, options.profile, options.emulateRoleVia, options.assumeRole !== void 0 ? "--assume-role" : "--assume-task-role");
|
|
19968
20070
|
} else if (typeof effectiveAssumeRole === "string") {
|
|
19969
20071
|
resolvedRoleArn = effectiveAssumeRole;
|
|
19970
|
-
assumedCredentials = await assumeTaskRole$1(resolvedRoleArn, options.region, options.profile);
|
|
20072
|
+
assumedCredentials = await assumeTaskRole$1(resolvedRoleArn, options.region, options.profile, options.emulateRoleVia, options.assumeRole !== void 0 ? "--assume-role" : "--assume-task-role");
|
|
19971
20073
|
}
|
|
19972
20074
|
const mixedWiring = getActiveWorkloadAwsWiring()?.mixed;
|
|
19973
20075
|
if (!mixedWiring && discovery.sharedNetwork && resolvedRoleArn !== void 0 && assumedCredentials) try {
|
|
@@ -20051,7 +20153,8 @@ async function resolveAlbLambdaTargetEnv(plan, options, extraStateProviders) {
|
|
|
20051
20153
|
...options.region !== void 0 && { region: options.region },
|
|
20052
20154
|
...options.profile !== void 0 && { profile: options.profile },
|
|
20053
20155
|
...options.stackRegion !== void 0 && { stackRegion: options.stackRegion },
|
|
20054
|
-
...options.envVars !== void 0 && { envVars: options.envVars }
|
|
20156
|
+
...options.envVars !== void 0 && { envVars: options.envVars },
|
|
20157
|
+
...options.emulateRoleVia !== void 0 && { emulateRoleVia: options.emulateRoleVia }
|
|
20055
20158
|
};
|
|
20056
20159
|
const profileCredentials = options.profile ? await resolveProfileCredentials(options.profile) : void 0;
|
|
20057
20160
|
for (const [logicalId, lambda] of lambdas) out.set(logicalId, await resolveLambdaContainerEnv(lambda, envOptions, profileCredentials, extraStateProviders));
|
|
@@ -20303,7 +20406,7 @@ function describeForwardTargetForSummary(t) {
|
|
|
20303
20406
|
return t.kind === "lambda" ? `<Lambda: ${displayIdent(t.lambda.logicalId)}>` : `<ECS: ${displayStackName(t.serviceTarget)}>`;
|
|
20304
20407
|
}
|
|
20305
20408
|
async function resolvePlaceholderAccount$1(arn, region, profile, readFromCfnStack) {
|
|
20306
|
-
if (!arn
|
|
20409
|
+
if (!hasTaskRolePlaceholder(arn)) return arn;
|
|
20307
20410
|
const { STSClient, GetCallerIdentityCommand } = await import("@aws-sdk/client-sts");
|
|
20308
20411
|
const sts = new STSClient(accountLookupStsClientConfig({
|
|
20309
20412
|
region,
|
|
@@ -20311,9 +20414,10 @@ async function resolvePlaceholderAccount$1(arn, region, profile, readFromCfnStac
|
|
|
20311
20414
|
readFromCfnStack
|
|
20312
20415
|
}));
|
|
20313
20416
|
try {
|
|
20314
|
-
const
|
|
20417
|
+
const identity = await sts.send(new GetCallerIdentityCommand({}));
|
|
20418
|
+
const account = identity.Account;
|
|
20315
20419
|
if (!account) throw new LocalStartServiceError(`--assume-task-role: GetCallerIdentity returned no Account; cannot resolve placeholder ARN ${displayUntrustedValue(arn)}.`);
|
|
20316
|
-
return arn.
|
|
20420
|
+
return fillTaskRolePlaceholders(arn, account, identity.Arn);
|
|
20317
20421
|
} catch (err) {
|
|
20318
20422
|
if (err instanceof LocalStartServiceError) throw err;
|
|
20319
20423
|
throw new LocalStartServiceError(`--assume-task-role: STS GetCallerIdentity failed while resolving placeholder ARN ${displayUntrustedValue(arn)}: ${describeAwsFailureForWarn(err, "STS GetCallerIdentity (task-role placeholder)")}. Pass the ARN explicitly: --assume-task-role <arn>`);
|
|
@@ -20324,13 +20428,15 @@ async function resolvePlaceholderAccount$1(arn, region, profile, readFromCfnStac
|
|
|
20324
20428
|
async function resolveTaskRoleArnForOptions$1(arn, options) {
|
|
20325
20429
|
return resolvePlaceholderAccount$1(arn, options.region, options.profile, isCfnFlagPresent(options));
|
|
20326
20430
|
}
|
|
20327
|
-
async function assumeTaskRole$1(roleArn, region, profile) {
|
|
20431
|
+
async function assumeTaskRole$1(roleArn, region, profile, emulateRoleVia, roleFlag = "--assume-role") {
|
|
20328
20432
|
return assumeRoleCredentials({
|
|
20329
20433
|
roleArn,
|
|
20330
20434
|
region,
|
|
20331
20435
|
profile,
|
|
20332
20436
|
sessionNameSuffix: "start-service",
|
|
20333
|
-
makeError: (message) => new LocalStartServiceError(message)
|
|
20437
|
+
makeError: (message) => new LocalStartServiceError(message),
|
|
20438
|
+
emulateRoleVia,
|
|
20439
|
+
roleFlag
|
|
20334
20440
|
});
|
|
20335
20441
|
}
|
|
20336
20442
|
async function createTargetStateProviders(target, stacks, options, extraStateProviders) {
|
|
@@ -20395,8 +20501,11 @@ async function buildEcsImageResolutionContext$1(target, stacks, options, statePr
|
|
|
20395
20501
|
const candidate = pickCandidateStack$1(target, stacks);
|
|
20396
20502
|
if (!candidate) return void 0;
|
|
20397
20503
|
const needs = detectEcsImageResolutionNeeds(candidate);
|
|
20398
|
-
|
|
20504
|
+
const roleRecordUsable = !taskRoleRecordIsEmulatorSide();
|
|
20505
|
+
const wantsStateForTaskRole = !!stateProvider && needs.needsTaskRoleState && isBareAssumeRole(options) && roleRecordUsable;
|
|
20506
|
+
if (!needs.needsPseudoParameters && !needs.needsStateResources && !needs.needsEnvOrSecretSubstitution && !wantsStateForTaskRole) return;
|
|
20399
20507
|
const ctx = {};
|
|
20508
|
+
if (!roleRecordUsable) ctx.ignoreStateForRoles = true;
|
|
20400
20509
|
const wantsPseudoForEnvOrSecret = !!stateProvider && needs.needsEnvOrSecretSubstitution;
|
|
20401
20510
|
if (needs.needsPseudoParameters || wantsPseudoForEnvOrSecret) {
|
|
20402
20511
|
const region = options.region ?? process.env["AWS_REGION"] ?? process.env["AWS_DEFAULT_REGION"] ?? candidate.region;
|
|
@@ -20417,12 +20526,16 @@ async function buildEcsImageResolutionContext$1(target, stacks, options, statePr
|
|
|
20417
20526
|
}
|
|
20418
20527
|
};
|
|
20419
20528
|
}
|
|
20420
|
-
const wantsState = needs.needsStateResources || needs.needsEnvOrSecretSubstitution;
|
|
20529
|
+
const wantsState = needs.needsStateResources || needs.needsEnvOrSecretSubstitution || wantsStateForTaskRole;
|
|
20421
20530
|
if (stateProvider && wantsState) {
|
|
20422
20531
|
const loaded = await stateProvider.load(candidate.stackName, candidate.region);
|
|
20423
20532
|
if (loaded) {
|
|
20424
20533
|
ctx.stateResources = loaded.resources;
|
|
20425
20534
|
ctx.stateRegion = loaded.region;
|
|
20535
|
+
if (loaded.realSideUnread) {
|
|
20536
|
+
ctx.ignoreStateForRoles = true;
|
|
20537
|
+
ctx.roleRecordRealSideUnread = true;
|
|
20538
|
+
}
|
|
20426
20539
|
} else {
|
|
20427
20540
|
const loadError = stateProvider.getLastLoadError?.();
|
|
20428
20541
|
if (loadError) ctx.stateLoadFailureMessage = loadError;
|
|
@@ -20613,7 +20726,7 @@ function ecsClusterOption() {
|
|
|
20613
20726
|
return new Option("--cluster <name>", "Cluster name surfaced to ECS_CONTAINER_METADATA_URI_V4 and used as the docker network prefix").default(getEmbedConfig().resourceNamePrefix);
|
|
20614
20727
|
}
|
|
20615
20728
|
function addEcsAssumeRoleOptions(cmd) {
|
|
20616
|
-
return cmd.addOption(new Option("--assume-task-role [arn]", "Assume the task definition's TaskRoleArn (or the supplied ARN) and forward STS-issued temp credentials via the metadata sidecar so containers run with the deployed task role. Bare flag uses the template's TaskRoleArn; pass an explicit ARN to override. DEPRECATED alias of `--assume-role`; both forms work, but `--assume-role` is the cross-command name and will become the only form in a future release.")).addOption(new Option("--assume-role [arn]", "Assume the task definition's TaskRoleArn (or the supplied ARN) and forward STS-issued temp credentials via the metadata sidecar so containers run with the deployed task role. Bare flag uses the template's TaskRoleArn; pass an explicit ARN to override. Cross-command alias matching the same flag on `invoke` / `invoke-agentcore` / `start-api`; supersedes the older `--assume-task-role` (which still works)."));
|
|
20729
|
+
return cmd.addOption(new Option("--assume-task-role [arn]", "Assume the task definition's TaskRoleArn (or the supplied ARN) and forward STS-issued temp credentials via the metadata sidecar so containers run with the deployed task role. Bare flag uses the template's TaskRoleArn; pass an explicit ARN to override. DEPRECATED alias of `--assume-role`; both forms work, but `--assume-role` is the cross-command name and will become the only form in a future release.")).addOption(new Option("--assume-role [arn]", "Assume the task definition's TaskRoleArn (or the supplied ARN) and forward STS-issued temp credentials via the metadata sidecar so containers run with the deployed task role. Bare flag uses the template's TaskRoleArn; pass an explicit ARN to override. Cross-command alias matching the same flag on `invoke` / `invoke-agentcore` / `start-api`; supersedes the older `--assume-task-role` (which still works).")).addOption(emulateRoleViaOption("--assume-role"));
|
|
20617
20730
|
}
|
|
20618
20731
|
let assumeTaskRoleDeprecationWarned = false;
|
|
20619
20732
|
function isTaskRoleInEffect(options) {
|
|
@@ -20646,6 +20759,25 @@ function addCommonEcsServiceOptions(cmd) {
|
|
|
20646
20759
|
function addImageOverrideOptions(cmd) {
|
|
20647
20760
|
return cmd.addOption(new Option("--image-override <service=dockerfile or dockerfile...>", "Replace a service target's deployed-registry image with a local `docker build` of the supplied Dockerfile (repeatable). Two forms: <service>=<dockerfile> binds the service explicitly; a bare <dockerfile> opens a multi-select picker against the still-uncovered pinned targets (one Dockerfile across N services). Mix freely. Lets `--from-cfn-stack` still reach real AWS state while you iterate locally on the application container.")).addOption(new Option("--image-build-arg <KEY=VAL...>", "Global `docker build --build-arg KEY=VAL` pair applied to every --image-override build (repeatable). Lets a CDK Dockerfile that branches on an ARG (env target, base image tag, package mirror) honor that ARG locally without editing the Dockerfile.")).addOption(new Option("--image-build-secret <id=src...>", "Global `docker build --secret id=<id>,src=<src>` entry applied to every --image-override build (repeatable). Enables `RUN --mount=type=secret,id=<id>` in the Dockerfile — the standard private-registry / npm-token recipe (e.g. `--image-build-secret npmrc=./.npmrc`).")).addOption(new Option("--image-target <stage or svc=stage...>", "Repeatable. Bare `<stage>` is a global --target for every --image-override build; `<service>=<stage>` (issue #240) scopes the --target to one overridden target so a monorepo with different multi-stage Dockerfiles per service can stop each at its own intermediate stage. Per-service form overrides the global on the named target.")).addOption(new Option("--image-context <dir or svc=dir...>", "Repeatable. The `docker build` context for --image-override builds whose Dockerfile lives below it (a monorepo whose apps share code: --image-override Svc=apps/api/Dockerfile --image-context Svc=.). Bare `<dir>` applies to every overridden target; `<service>=<dir>` scopes it to one and overrides the global. Default: the Dockerfile's directory.")).addOption(new Option("--no-interactive-overrides", "Suppress the interactive boot prompt that walks each pinned target asking for a Dockerfile path, and the multi-select prompt fired by `--image-override <dockerfile>` (picker form). Useful for CI / scripted invocations.")).addOption(new Option("--strict-overrides", "Fail fast at boot when any pinned target remains uncovered after `--image-override` + the boot prompt resolve. Off by default; the boot WARN per uncovered pinned target still fires regardless.").default(false));
|
|
20648
20761
|
}
|
|
20762
|
+
function isBareAssumeRole(options) {
|
|
20763
|
+
return (options.assumeRole ?? options.assumeTaskRole) === true;
|
|
20764
|
+
}
|
|
20765
|
+
function taskRoleRecordIsEmulatorSide() {
|
|
20766
|
+
return getActiveWorkloadAwsWiring()?.mixed !== void 0 && isAwsServiceRoutedToEmulator("IAM");
|
|
20767
|
+
}
|
|
20768
|
+
function warnIfTaskRoleIsLogicalId(task, stateProvider, imageContext) {
|
|
20769
|
+
if (task.taskRoleUnresolved === void 0) return;
|
|
20770
|
+
const { logicalId, reason } = task.taskRoleUnresolved;
|
|
20771
|
+
const id = displayIdent(logicalId);
|
|
20772
|
+
const explicit = "or pass the ARN explicitly: --assume-role '<arn>'.";
|
|
20773
|
+
let why;
|
|
20774
|
+
if (!stateProvider) why = `without a state-source flag (e.g. --from-cfn-stack) ${getEmbedConfig().binaryName} cannot read the name it was deployed under. A role CDK names for you is deployed as '<Stack>-<LogicalId>-<suffix>', where AssumeRole fails: pass a state-source flag, ${explicit}`;
|
|
20775
|
+
else if (imageContext?.roleRecordRealSideUnread) why = `in AWS Emulator mixed mode the stack could not be read from real AWS, so the record holds only the emulator's role, which is not assumed in real AWS. Deploy the stack to real AWS too, ${explicit}`;
|
|
20776
|
+
else if (imageContext?.ignoreStateForRoles || taskRoleRecordIsEmulatorSide()) why = `in AWS Emulator mixed mode the task role is assumed in real AWS, but the state record's IAM roles are the emulator's, so it is not read. Mark IAM as a "real-aws" exception under Parameters (AWS_ENDPOINT_URL_IAM), ${explicit}`;
|
|
20777
|
+
else if (reason === "path-not-literal") why = `the template's Path for it is not a literal IAM path, so its ARN cannot be built from the stack's record. Pass the ARN explicitly: --assume-role '<arn>'.`;
|
|
20778
|
+
else why = `the state source has no record of it (is the stack deployed?). Deploy the stack first, ${explicit}`;
|
|
20779
|
+
getLogger().warn(`--assume-role: TaskRoleArn references the same-stack role ${id}, so a role named ${id} is assumed: ${why}`);
|
|
20780
|
+
}
|
|
20649
20781
|
|
|
20650
20782
|
//#endregion
|
|
20651
20783
|
//#region src/cli/commands/local-run-task.ts
|
|
@@ -20676,6 +20808,10 @@ async function localRunTaskCommand(target, options, extraStateProviders) {
|
|
|
20676
20808
|
};
|
|
20677
20809
|
try {
|
|
20678
20810
|
await activateWorkloadAwsWiring(options);
|
|
20811
|
+
warnIfEmulateRoleViaUnused(options.emulateRoleVia, {
|
|
20812
|
+
roleFlag: "--assume-role",
|
|
20813
|
+
roleRequested: isRoleFlagRequested(options.assumeRole ?? options.assumeTaskRole)
|
|
20814
|
+
});
|
|
20679
20815
|
await applyRoleArnIfSet({
|
|
20680
20816
|
roleArn: options.roleArn,
|
|
20681
20817
|
region: options.region,
|
|
@@ -20734,11 +20870,12 @@ async function localRunTaskCommand(target, options, extraStateProviders) {
|
|
|
20734
20870
|
let resolvedRoleArn;
|
|
20735
20871
|
if (effectiveAssumeRole === true) {
|
|
20736
20872
|
if (!task.taskRoleArn) throw new Error(`--assume-role passed without an ARN but the task definition has no resolvable TaskRoleArn. Either the task definition does not set TaskRoleArn, or it points at a resource ${getEmbedConfig().binaryName} cannot resolve to an IAM Role at synth time. Pass the ARN explicitly: --assume-role <arn>`);
|
|
20873
|
+
warnIfTaskRoleIsLogicalId(task, stateProvider, imageContext);
|
|
20737
20874
|
resolvedRoleArn = await resolveTaskRoleArnForOptions(task.taskRoleArn, options);
|
|
20738
|
-
assumedCredentials = await assumeTaskRole(resolvedRoleArn, options.region, options.profile);
|
|
20875
|
+
assumedCredentials = await assumeTaskRole(resolvedRoleArn, options.region, options.profile, options.emulateRoleVia, options.assumeRole !== void 0 ? "--assume-role" : "--assume-task-role");
|
|
20739
20876
|
} else if (typeof effectiveAssumeRole === "string") {
|
|
20740
20877
|
resolvedRoleArn = effectiveAssumeRole;
|
|
20741
|
-
assumedCredentials = await assumeTaskRole(resolvedRoleArn, options.region, options.profile);
|
|
20878
|
+
assumedCredentials = await assumeTaskRole(resolvedRoleArn, options.region, options.profile, options.emulateRoleVia, options.assumeRole !== void 0 ? "--assume-role" : "--assume-task-role");
|
|
20742
20879
|
}
|
|
20743
20880
|
const sidecarCredentials = await resolveSidecarCredentials(options, assumedCredentials);
|
|
20744
20881
|
const credsDelivery = containerCredentialDelivery(options, sidecarCredentials, assumedCredentials);
|
|
@@ -20821,7 +20958,7 @@ var PlaceholderAccountError = class PlaceholderAccountError extends Error {
|
|
|
20821
20958
|
}
|
|
20822
20959
|
};
|
|
20823
20960
|
async function resolvePlaceholderAccount(arn, region, profile, readFromCfnStack) {
|
|
20824
|
-
if (!arn
|
|
20961
|
+
if (!hasTaskRolePlaceholder(arn)) return arn;
|
|
20825
20962
|
const { STSClient, GetCallerIdentityCommand } = await import("@aws-sdk/client-sts");
|
|
20826
20963
|
const sts = new STSClient(accountLookupStsClientConfig({
|
|
20827
20964
|
region,
|
|
@@ -20829,9 +20966,10 @@ async function resolvePlaceholderAccount(arn, region, profile, readFromCfnStack)
|
|
|
20829
20966
|
readFromCfnStack
|
|
20830
20967
|
}));
|
|
20831
20968
|
try {
|
|
20832
|
-
const
|
|
20969
|
+
const identity = await sts.send(new GetCallerIdentityCommand({}));
|
|
20970
|
+
const account = identity.Account;
|
|
20833
20971
|
if (!account) throw new PlaceholderAccountError(`--assume-task-role: GetCallerIdentity returned no Account; cannot resolve placeholder ARN ${displayUntrustedValue(arn)}. Pass the ARN explicitly: --assume-task-role <arn>`);
|
|
20834
|
-
return arn.
|
|
20972
|
+
return fillTaskRolePlaceholders(arn, account, identity.Arn);
|
|
20835
20973
|
} catch (err) {
|
|
20836
20974
|
if (err instanceof PlaceholderAccountError) throw err;
|
|
20837
20975
|
const shownArn = displayUntrustedValue(arn);
|
|
@@ -20844,20 +20982,25 @@ async function resolvePlaceholderAccount(arn, region, profile, readFromCfnStack)
|
|
|
20844
20982
|
async function resolveTaskRoleArnForOptions(arn, options) {
|
|
20845
20983
|
return resolvePlaceholderAccount(arn, options.region, options.profile, isCfnFlagPresent(options));
|
|
20846
20984
|
}
|
|
20847
|
-
async function assumeTaskRole(roleArn, region, profile) {
|
|
20985
|
+
async function assumeTaskRole(roleArn, region, profile, emulateRoleVia, roleFlag = "--assume-role") {
|
|
20848
20986
|
return assumeRoleCredentials({
|
|
20849
20987
|
roleArn,
|
|
20850
20988
|
region,
|
|
20851
20989
|
profile,
|
|
20852
|
-
sessionNameSuffix: "run-task"
|
|
20990
|
+
sessionNameSuffix: "run-task",
|
|
20991
|
+
emulateRoleVia,
|
|
20992
|
+
roleFlag
|
|
20853
20993
|
});
|
|
20854
20994
|
}
|
|
20855
20995
|
async function buildEcsImageResolutionContext(candidate, stateProvider, options, stateProviderFor) {
|
|
20856
20996
|
const logger = getLogger();
|
|
20857
20997
|
if (!candidate) return void 0;
|
|
20858
20998
|
const needs = detectEcsImageResolutionNeeds(candidate);
|
|
20859
|
-
|
|
20999
|
+
const roleRecordUsable = !taskRoleRecordIsEmulatorSide();
|
|
21000
|
+
const wantsStateForTaskRole = !!stateProvider && needs.needsTaskRoleState && isBareAssumeRole(options) && roleRecordUsable;
|
|
21001
|
+
if (!needs.needsPseudoParameters && !needs.needsStateResources && !needs.needsEnvOrSecretSubstitution && !wantsStateForTaskRole) return;
|
|
20860
21002
|
const ctx = {};
|
|
21003
|
+
if (!roleRecordUsable) ctx.ignoreStateForRoles = true;
|
|
20861
21004
|
const wantsPseudoForEnvOrSecret = !!stateProvider && needs.needsEnvOrSecretSubstitution;
|
|
20862
21005
|
if (needs.needsPseudoParameters || wantsPseudoForEnvOrSecret) {
|
|
20863
21006
|
const region = options.region ?? process.env["AWS_REGION"] ?? process.env["AWS_DEFAULT_REGION"] ?? candidate.region;
|
|
@@ -20878,12 +21021,16 @@ async function buildEcsImageResolutionContext(candidate, stateProvider, options,
|
|
|
20878
21021
|
}
|
|
20879
21022
|
};
|
|
20880
21023
|
}
|
|
20881
|
-
const wantsState = needs.needsStateResources || needs.needsEnvOrSecretSubstitution;
|
|
21024
|
+
const wantsState = needs.needsStateResources || needs.needsEnvOrSecretSubstitution || wantsStateForTaskRole;
|
|
20882
21025
|
if (stateProvider && wantsState) {
|
|
20883
21026
|
const loaded = await stateProvider.load(candidate.stackName, candidate.region);
|
|
20884
21027
|
if (loaded) {
|
|
20885
21028
|
ctx.stateResources = loaded.resources;
|
|
20886
21029
|
ctx.stateRegion = loaded.region;
|
|
21030
|
+
if (loaded.realSideUnread) {
|
|
21031
|
+
ctx.ignoreStateForRoles = true;
|
|
21032
|
+
ctx.roleRecordRealSideUnread = true;
|
|
21033
|
+
}
|
|
20887
21034
|
} else {
|
|
20888
21035
|
const loadError = stateProvider.getLastLoadError?.();
|
|
20889
21036
|
if (loadError) ctx.stateLoadFailureMessage = loadError;
|
|
@@ -24787,7 +24934,8 @@ function buildLambdaEnvOptions(options, extraStateProviders) {
|
|
|
24787
24934
|
...options.region !== void 0 && { region: options.region },
|
|
24788
24935
|
...options.profile !== void 0 && { profile: options.profile },
|
|
24789
24936
|
...options.stackRegion !== void 0 && { stackRegion: options.stackRegion },
|
|
24790
|
-
...options.envVars !== void 0 && { envVars: options.envVars }
|
|
24937
|
+
...options.envVars !== void 0 && { envVars: options.envVars },
|
|
24938
|
+
...options.emulateRoleVia !== void 0 && { emulateRoleVia: options.emulateRoleVia }
|
|
24791
24939
|
};
|
|
24792
24940
|
}
|
|
24793
24941
|
function lambdaEdgeEnvOptions(envOptions) {
|
|
@@ -24890,6 +25038,10 @@ async function localStartCloudFrontCommand(target, options, extraStateProviders,
|
|
|
24890
25038
|
const originOverrides = parseOriginOverrides(options.origin);
|
|
24891
25039
|
const tlsRequested = options.tls === true || options.tlsCert !== void 0 || options.tlsKey !== void 0;
|
|
24892
25040
|
await activateWorkloadAwsWiring(options);
|
|
25041
|
+
warnIfEmulateRoleViaUnused(options.emulateRoleVia, {
|
|
25042
|
+
roleFlag: "--assume-role",
|
|
25043
|
+
roleRequested: options.assumeRole !== void 0 && options.assumeRole !== false
|
|
25044
|
+
});
|
|
24893
25045
|
await applyRoleArnIfSet({
|
|
24894
25046
|
roleArn: options.roleArn,
|
|
24895
25047
|
region: options.region,
|
|
@@ -25065,7 +25217,7 @@ function createLocalStartCloudFrontCommand(opts = {}) {
|
|
|
25065
25217
|
}
|
|
25066
25218
|
function addStartCloudFrontSpecificOptions(cmd) {
|
|
25067
25219
|
addAwsEndpointOptions(cmd);
|
|
25068
|
-
return cmd.addOption(new Option("--port <port>", "HTTP server port (default: auto-allocate)").default("0")).addOption(new Option("--host <host>", "Bind address").default("127.0.0.1")).addOption(new Option("--origin <originId=dir>", "Point a distribution origin at a local directory (repeatable). Use when cdk-local cannot resolve the origin's BucketDeployment source automatically (content uploaded out of band, or a non-CDK bucket).").argParser((value, prev) => [...prev ?? [], value])).addOption(new Option("--kvs-file <key=file.json>", "Back a CloudFront Function's KeyValueStore reads (cf.kvs().get()) with a local JSON map (repeatable). The key is a KeyValueStore handle — its AWS::CloudFront::KeyValueStore resource logical id, its construct path, or its bare construct id; the file is a flat { \"key\": \"value\" } object. The AWS-free alternative to --from-cfn-stack, which instead reads the deployed store via the GetKey API.").argParser((value, prev) => [...prev ?? [], value])).addOption(new Option("--tls", "Terminate real TLS (HTTPS). Uses --tls-cert / --tls-key when supplied, else an auto-generated self-signed cert.").default(false)).addOption(new Option("--tls-cert <path>", "PEM server certificate for --tls (implies --tls).")).addOption(new Option("--tls-key <path>", "PEM server private key for --tls (implies --tls).")).addOption(new Option("--no-pull", "Skip 'docker pull' for a Lambda Function URL / Web Function origin's base image (use the locally cached image).")).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Bind to a deployed CloudFormation stack (ListStackResources). Resolves an S3 origin that has no local BucketDeployment source to its deployed bucket and serves it from real S3 on demand (the front/back-split case: files uploaded out of band), and resolves a Lambda Function URL / Lambda@Edge function's or a Web Function origin revision's env vars to the deployed physical IDs / exports. Use for CDK apps deployed via the upstream CDK CLI (`cdk deploy`). Bare form uses the resolved stack name; pass a value when the CFn stack name differs.")).addOption(new Option("--cache-origin", "For a deployed-S3 origin (served from real S3 under --from-cfn-stack): keep fetched objects in memory for the session instead of re-reading on every request. Faster repeat reads / fewer S3 GETs, but an out-of-band S3 content change is not reflected until a --watch reload (which clears the cache) or a restart. Off by default (every request re-reads, always current). Not CloudFront CDN caching.").default(false)).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-cfn-stack as the CFn client region.")).addOption(new Option("--assume-role [arn]", "Assume a Lambda Function URL origin's (or a Web Function origin revision's) execution role and forward STS-issued temp credentials into its container so the handler runs with the deployed permissions. Three forms: `--assume-role <arn>` (explicit ARN); `--assume-role` (bare, auto-resolves from state — requires --from-cfn-stack); `--no-assume-role` (opt out). Off by default (the dev shell credentials are forwarded).")).addOption(new Option("--env-vars <file>", "JSON env-var overrides for the Lambda Function URL and Lambda Web Function endpoint origins (SAM-compatible, the same file as the other commands: {\"Parameters\": {...}} for every origin, {\"<LogicalId or construct path>\": {\"KEY\": \"VALUE\"}} for one — the backing function, or the Web Function revision the endpoint serves; a null value removes the variable). Not applied to Lambda@Edge functions, which cannot carry environment variables in AWS.")).addOption(new Option("--watch", "Hot-reload: re-synth + re-resolve the distribution when the CDK app's source changes (honors cdk.json watch.include/exclude; cdk.out, cdk.context.json, node_modules, .git are always excluded). The server keeps the previous version serving when synth fails mid-reload.").default(false));
|
|
25220
|
+
return cmd.addOption(new Option("--port <port>", "HTTP server port (default: auto-allocate)").default("0")).addOption(new Option("--host <host>", "Bind address").default("127.0.0.1")).addOption(new Option("--origin <originId=dir>", "Point a distribution origin at a local directory (repeatable). Use when cdk-local cannot resolve the origin's BucketDeployment source automatically (content uploaded out of band, or a non-CDK bucket).").argParser((value, prev) => [...prev ?? [], value])).addOption(new Option("--kvs-file <key=file.json>", "Back a CloudFront Function's KeyValueStore reads (cf.kvs().get()) with a local JSON map (repeatable). The key is a KeyValueStore handle — its AWS::CloudFront::KeyValueStore resource logical id, its construct path, or its bare construct id; the file is a flat { \"key\": \"value\" } object. The AWS-free alternative to --from-cfn-stack, which instead reads the deployed store via the GetKey API.").argParser((value, prev) => [...prev ?? [], value])).addOption(new Option("--tls", "Terminate real TLS (HTTPS). Uses --tls-cert / --tls-key when supplied, else an auto-generated self-signed cert.").default(false)).addOption(new Option("--tls-cert <path>", "PEM server certificate for --tls (implies --tls).")).addOption(new Option("--tls-key <path>", "PEM server private key for --tls (implies --tls).")).addOption(new Option("--no-pull", "Skip 'docker pull' for a Lambda Function URL / Web Function origin's base image (use the locally cached image).")).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Bind to a deployed CloudFormation stack (ListStackResources). Resolves an S3 origin that has no local BucketDeployment source to its deployed bucket and serves it from real S3 on demand (the front/back-split case: files uploaded out of band), and resolves a Lambda Function URL / Lambda@Edge function's or a Web Function origin revision's env vars to the deployed physical IDs / exports. Use for CDK apps deployed via the upstream CDK CLI (`cdk deploy`). Bare form uses the resolved stack name; pass a value when the CFn stack name differs.")).addOption(new Option("--cache-origin", "For a deployed-S3 origin (served from real S3 under --from-cfn-stack): keep fetched objects in memory for the session instead of re-reading on every request. Faster repeat reads / fewer S3 GETs, but an out-of-band S3 content change is not reflected until a --watch reload (which clears the cache) or a restart. Off by default (every request re-reads, always current). Not CloudFront CDN caching.").default(false)).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-cfn-stack as the CFn client region.")).addOption(new Option("--assume-role [arn]", "Assume a Lambda Function URL origin's (or a Web Function origin revision's) execution role and forward STS-issued temp credentials into its container so the handler runs with the deployed permissions. Three forms: `--assume-role <arn>` (explicit ARN); `--assume-role` (bare, auto-resolves from state — requires --from-cfn-stack); `--no-assume-role` (opt out). Off by default (the dev shell credentials are forwarded).")).addOption(emulateRoleViaOption("--assume-role")).addOption(new Option("--env-vars <file>", "JSON env-var overrides for the Lambda Function URL and Lambda Web Function endpoint origins (SAM-compatible, the same file as the other commands: {\"Parameters\": {...}} for every origin, {\"<LogicalId or construct path>\": {\"KEY\": \"VALUE\"}} for one — the backing function, or the Web Function revision the endpoint serves; a null value removes the variable). Not applied to Lambda@Edge functions, which cannot carry environment variables in AWS.")).addOption(new Option("--watch", "Hot-reload: re-synth + re-resolve the distribution when the CDK app's source changes (honors cdk.json watch.include/exclude; cdk.out, cdk.context.json, node_modules, .git are always excluded). The server keeps the previous version serving when synth fails mid-reload.").default(false));
|
|
25069
25221
|
}
|
|
25070
25222
|
|
|
25071
25223
|
//#endregion
|
|
@@ -25451,6 +25603,10 @@ async function localStartAgentCoreCommand(target, options, extraStateProviders,
|
|
|
25451
25603
|
} catch {}
|
|
25452
25604
|
};
|
|
25453
25605
|
await activateWorkloadAwsWiring(options);
|
|
25606
|
+
warnIfEmulateRoleViaUnused(options.emulateRoleVia, {
|
|
25607
|
+
roleFlag: "--assume-role",
|
|
25608
|
+
roleRequested: options.assumeRole !== void 0 && options.assumeRole !== false
|
|
25609
|
+
});
|
|
25454
25610
|
await applyRoleArnIfSet({
|
|
25455
25611
|
roleArn: options.roleArn,
|
|
25456
25612
|
region: options.region,
|
|
@@ -25706,7 +25862,7 @@ function createLocalStartAgentCoreCommand(opts = {}) {
|
|
|
25706
25862
|
}
|
|
25707
25863
|
function addStartAgentCoreSpecificOptions(cmd) {
|
|
25708
25864
|
addAwsEndpointOptions(cmd);
|
|
25709
|
-
return cmd.addOption(new Option("--port <n>", "Serve bind port the client connects to (HTTP contract + /ws on the same port). Default 0 (OS-assigned).").default(0).argParser(parsePort$2)).addOption(new Option("--host <ip>", "Serve bind host. Default 127.0.0.1.").default("127.0.0.1")).addOption(new Option("--session-id <id>", "Pin one AgentCore runtime session id header value for every forwarded request / /ws connection (default: a fresh random UUID each, so each is its own session).")).addOption(new Option("--bearer-token <jwt>", "Bearer JWT to present when the runtime declares a customJwtAuthorizer. Verified against the runtime's OIDC discovery URL before the container starts, then injected as Authorization: Bearer <jwt> on every forwarded request and the container /ws upgrade.")).addOption(new Option("--no-verify-auth", "Skip inbound JWT verification even when the runtime declares a customJwtAuthorizer (local-dev escape hatch). A --bearer-token, if given, is still forwarded.")).addOption(new Option("--sigv4", "Sign each forwarded request with AWS SigV4 (service bedrock-agentcore) when the runtime declares NO customJwtAuthorizer, so the warm container sees the same Authorization / X-Amz-* headers the cloud receives. Mutually exclusive with --bearer-token; ignored (with a warning) when a customJwtAuthorizer is declared.")).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"LogicalId\":{\"KEY\":\"VALUE\"}, \"Parameters\": {...}})")).addOption(new Option("--platform <platform>", "docker --platform for the agent container (linux/amd64 or linux/arm64). Defaults to linux/arm64 because the cloud AgentCore Runtime requires arm64.").choices(["linux/amd64", "linux/arm64"]).default("linux/arm64")).addOption(new Option("--watch", "Re-synth + reload the warm container in place on a CDK source change, keeping the serve up. A per-firing classifier picks rebuild (boot a fresh container, re-point the serve) vs soft-reload (docker cp + docker restart the same container) — the same pattern as start-service / invoke-agentcore --ws --watch.")).addOption(new Option("--no-pull", "Skip docker pull (use cached image) — no-op for the local-build path")).addOption(new Option("--no-build", "Skip docker build on the local-asset path (use the previously-built tag). No-op for the ECR / registry pull paths.")).addOption(new Option("--container-host <host>", "Host IP used to bind the agent container port. Must be a numeric IP. Defaults to 127.0.0.1.").default("127.0.0.1")).addOption(new Option("--timeout <ms>", "Maximum time in milliseconds to wait for the container to become ready (the GET /ping readiness deadline). Default 120000.").default(12e4).argParser(parseTimeoutMs)).addOption(new Option("--assume-role [arn]", "Assume the runtime's execution role and forward STS-issued temp credentials to the container. (1) `--assume-role <arn>` assumes the explicit ARN; (2) `--assume-role` (bare) uses the runtime's literal RoleArn; (3) `--no-assume-role` opts out. Off by default.")).addOption(new Option("--ecr-role-arn <arn>", "Role ARN to assume before authenticating against ECR for cross-account / centralized registries.")).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Read a deployed CloudFormation stack and substitute Ref / Fn::ImportValue in env vars / image URIs with the deployed physical IDs / exports. Bare form uses the resolved stack name.")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-cfn-stack as the CFn client region."));
|
|
25865
|
+
return cmd.addOption(new Option("--port <n>", "Serve bind port the client connects to (HTTP contract + /ws on the same port). Default 0 (OS-assigned).").default(0).argParser(parsePort$2)).addOption(new Option("--host <ip>", "Serve bind host. Default 127.0.0.1.").default("127.0.0.1")).addOption(new Option("--session-id <id>", "Pin one AgentCore runtime session id header value for every forwarded request / /ws connection (default: a fresh random UUID each, so each is its own session).")).addOption(new Option("--bearer-token <jwt>", "Bearer JWT to present when the runtime declares a customJwtAuthorizer. Verified against the runtime's OIDC discovery URL before the container starts, then injected as Authorization: Bearer <jwt> on every forwarded request and the container /ws upgrade.")).addOption(new Option("--no-verify-auth", "Skip inbound JWT verification even when the runtime declares a customJwtAuthorizer (local-dev escape hatch). A --bearer-token, if given, is still forwarded.")).addOption(new Option("--sigv4", "Sign each forwarded request with AWS SigV4 (service bedrock-agentcore) when the runtime declares NO customJwtAuthorizer, so the warm container sees the same Authorization / X-Amz-* headers the cloud receives. Mutually exclusive with --bearer-token; ignored (with a warning) when a customJwtAuthorizer is declared.")).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"LogicalId\":{\"KEY\":\"VALUE\"}, \"Parameters\": {...}})")).addOption(new Option("--platform <platform>", "docker --platform for the agent container (linux/amd64 or linux/arm64). Defaults to linux/arm64 because the cloud AgentCore Runtime requires arm64.").choices(["linux/amd64", "linux/arm64"]).default("linux/arm64")).addOption(new Option("--watch", "Re-synth + reload the warm container in place on a CDK source change, keeping the serve up. A per-firing classifier picks rebuild (boot a fresh container, re-point the serve) vs soft-reload (docker cp + docker restart the same container) — the same pattern as start-service / invoke-agentcore --ws --watch.")).addOption(new Option("--no-pull", "Skip docker pull (use cached image) — no-op for the local-build path")).addOption(new Option("--no-build", "Skip docker build on the local-asset path (use the previously-built tag). No-op for the ECR / registry pull paths.")).addOption(new Option("--container-host <host>", "Host IP used to bind the agent container port. Must be a numeric IP. Defaults to 127.0.0.1.").default("127.0.0.1")).addOption(new Option("--timeout <ms>", "Maximum time in milliseconds to wait for the container to become ready (the GET /ping readiness deadline). Default 120000.").default(12e4).argParser(parseTimeoutMs)).addOption(new Option("--assume-role [arn]", "Assume the runtime's execution role and forward STS-issued temp credentials to the container. (1) `--assume-role <arn>` assumes the explicit ARN; (2) `--assume-role` (bare) uses the runtime's literal RoleArn; (3) `--no-assume-role` opts out. Off by default.")).addOption(emulateRoleViaOption("--assume-role")).addOption(new Option("--ecr-role-arn <arn>", "Role ARN to assume before authenticating against ECR for cross-account / centralized registries.")).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Read a deployed CloudFormation stack and substitute Ref / Fn::ImportValue in env vars / image URIs with the deployed physical IDs / exports. Bare form uses the resolved stack name.")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-cfn-stack as the CFn client region."));
|
|
25710
25866
|
}
|
|
25711
25867
|
|
|
25712
25868
|
//#endregion
|
|
@@ -25721,6 +25877,10 @@ async function localStartWebFunctionCommand(target, options, extraStateProviders
|
|
|
25721
25877
|
if (options.verbose) logger.setLevel("debug");
|
|
25722
25878
|
const forever = () => new Promise(() => void 0);
|
|
25723
25879
|
await activateWorkloadAwsWiring(options);
|
|
25880
|
+
warnIfEmulateRoleViaUnused(options.emulateRoleVia, {
|
|
25881
|
+
roleFlag: "--assume-role",
|
|
25882
|
+
roleRequested: options.assumeRole !== void 0 && options.assumeRole !== false
|
|
25883
|
+
});
|
|
25724
25884
|
await applyRoleArnIfSet({
|
|
25725
25885
|
roleArn: options.roleArn,
|
|
25726
25886
|
region: options.region,
|
|
@@ -25820,7 +25980,7 @@ function createLocalStartWebFunctionCommand(opts = {}) {
|
|
|
25820
25980
|
}
|
|
25821
25981
|
function addStartWebFunctionSpecificOptions(cmd) {
|
|
25822
25982
|
addAwsEndpointOptions(cmd);
|
|
25823
|
-
return cmd.addOption(new Option("--revision <logicalId>", "Serve this WebFunctionRevision (logical ID) instead of the one the endpoint weights pick.")).addOption(new Option("--port <n>", "Local port to serve on. Default 0 (OS-assigned).").default(0).argParser(parsePort$1)).addOption(new Option("--host <ip>", "Address to publish the port on.").default("127.0.0.1")).addOption(new Option("--platform <platform>", "docker --platform for the server container. Defaults to the runtime's cloud architecture (linux/arm64 for nodejs24.x).").choices(["linux/amd64", "linux/arm64"])).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"RevisionLogicalId\":{\"KEY\":\"VALUE\"}, \"Parameters\": {...}})")).addOption(new Option("--no-pull", "Skip docker pull of the runtime base image (use the cached image)")).addOption(new Option("--timeout <ms>", "Maximum time in milliseconds to wait for the server to answer HTTP. Default 60000.").default(6e4).argParser(parseTimeoutMs)).addOption(new Option("--assume-role [arn]", "Assume the revision's execution role and forward STS-issued temp credentials to the container. (1) `--assume-role <arn>` assumes the explicit ARN; (2) `--assume-role` (bare) uses the revision's ServiceConfig.ExecutionRoleArn: a literal ARN as written, or the Fn::GetAtt / Ref CDK synthesizes resolved against --from-cfn-stack deployed state; (3) `--no-assume-role` opts out. Off by default.")).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Read a deployed CloudFormation stack and substitute Ref / Fn::ImportValue in env vars with the deployed physical IDs / exports. Bare form uses the resolved stack name.")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-cfn-stack as the CFn client region."));
|
|
25983
|
+
return cmd.addOption(new Option("--revision <logicalId>", "Serve this WebFunctionRevision (logical ID) instead of the one the endpoint weights pick.")).addOption(new Option("--port <n>", "Local port to serve on. Default 0 (OS-assigned).").default(0).argParser(parsePort$1)).addOption(new Option("--host <ip>", "Address to publish the port on.").default("127.0.0.1")).addOption(new Option("--platform <platform>", "docker --platform for the server container. Defaults to the runtime's cloud architecture (linux/arm64 for nodejs24.x).").choices(["linux/amd64", "linux/arm64"])).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"RevisionLogicalId\":{\"KEY\":\"VALUE\"}, \"Parameters\": {...}})")).addOption(new Option("--no-pull", "Skip docker pull of the runtime base image (use the cached image)")).addOption(new Option("--timeout <ms>", "Maximum time in milliseconds to wait for the server to answer HTTP. Default 60000.").default(6e4).argParser(parseTimeoutMs)).addOption(new Option("--assume-role [arn]", "Assume the revision's execution role and forward STS-issued temp credentials to the container. (1) `--assume-role <arn>` assumes the explicit ARN; (2) `--assume-role` (bare) uses the revision's ServiceConfig.ExecutionRoleArn: a literal ARN as written, or the Fn::GetAtt / Ref CDK synthesizes resolved against --from-cfn-stack deployed state; (3) `--no-assume-role` opts out. Off by default.")).addOption(emulateRoleViaOption("--assume-role")).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Read a deployed CloudFormation stack and substitute Ref / Fn::ImportValue in env vars with the deployed physical IDs / exports. Bare form uses the resolved stack name.")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-cfn-stack as the CFn client region."));
|
|
25824
25984
|
}
|
|
25825
25985
|
|
|
25826
25986
|
//#endregion
|
|
@@ -26831,6 +26991,10 @@ async function localStartMicrovmCommand(target, options, extraStateProviders, ho
|
|
|
26831
26991
|
};
|
|
26832
26992
|
const teardown = () => teardownPromise ??= doTeardown();
|
|
26833
26993
|
await activateWorkloadAwsWiring(options);
|
|
26994
|
+
warnIfEmulateRoleViaUnused(options.emulateRoleVia, {
|
|
26995
|
+
roleFlag: "--assume-role",
|
|
26996
|
+
roleRequested: options.assumeRole !== void 0
|
|
26997
|
+
});
|
|
26834
26998
|
await applyRoleArnIfSet({
|
|
26835
26999
|
roleArn: options.roleArn,
|
|
26836
27000
|
region: options.region,
|
|
@@ -27011,7 +27175,7 @@ function createLocalStartMicrovmCommand(opts = {}) {
|
|
|
27011
27175
|
}
|
|
27012
27176
|
function addStartMicrovmSpecificOptions(cmd) {
|
|
27013
27177
|
addAwsEndpointOptions(cmd);
|
|
27014
|
-
return cmd.addOption(new Option("--count <n>", "Number of independent MicroVMs to run, each with its own URL.").default(1).argParser(parseCount)).addOption(new Option("--run-hook-payload <string>", "The runHookPayload string delivered to each MicroVM's /run hook (max 16 KB).")).addOption(new Option("--run-hook-payload-file <path>", "Read the runHookPayload from a file (mutually exclusive with --run-hook-payload).")).addOption(new Option("--port <n>", "Local port of the first MicroVM; MicroVM i listens on <n>+i. Default 0 (OS-assigned).").default(0).argParser(parsePort)).addOption(new Option("--host <ip>", "Address the MicroVM URLs listen on.").default("127.0.0.1")).addOption(new Option("--platform <platform>", "docker --platform for the build and the containers. Defaults to the image's CpuConfigurations architecture.").choices(["linux/amd64", "linux/arm64"])).addOption(new Option("--proxy-port <port>", "An extra container port X-aws-proxy-port may route to (repeatable). 8080, Hooks.Port and the image's EXPOSE ports are always routable.").argParser(parseProxyPort)).addOption(new Option("--auto-resume", "Resume a suspended MicroVM on its next request instead of answering 503 (autoResumeEnabled).")).addOption(new Option("--no-build-cache", "Build the image with docker build --no-cache.")).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"MicrovmImageLogicalId\":{\"KEY\":\"VALUE\"}, \"Parameters\": {...}})")).addOption(new Option("--timeout <ms>", "Default deadline in milliseconds for each hook without its own <Hook>TimeoutInSeconds (/terminate defaults to 10000), and for the app to answer HTTP when there is no /ready hook. Default 60000.").default(6e4).argParser(parseTimeoutMs)).addOption(new Option("--assume-role <arn>", "Assume this role (the MicroVM's execution role, a run-microvm parameter rather than part of the template) and forward STS-issued temp credentials to the containers. Off by default: the shell credentials are forwarded.")).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Read a deployed CloudFormation stack and substitute Ref / Fn::ImportValue in env vars with the deployed physical IDs / exports. Bare form uses the resolved stack name.")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-cfn-stack as the CFn client region."));
|
|
27178
|
+
return cmd.addOption(new Option("--count <n>", "Number of independent MicroVMs to run, each with its own URL.").default(1).argParser(parseCount)).addOption(new Option("--run-hook-payload <string>", "The runHookPayload string delivered to each MicroVM's /run hook (max 16 KB).")).addOption(new Option("--run-hook-payload-file <path>", "Read the runHookPayload from a file (mutually exclusive with --run-hook-payload).")).addOption(new Option("--port <n>", "Local port of the first MicroVM; MicroVM i listens on <n>+i. Default 0 (OS-assigned).").default(0).argParser(parsePort)).addOption(new Option("--host <ip>", "Address the MicroVM URLs listen on.").default("127.0.0.1")).addOption(new Option("--platform <platform>", "docker --platform for the build and the containers. Defaults to the image's CpuConfigurations architecture.").choices(["linux/amd64", "linux/arm64"])).addOption(new Option("--proxy-port <port>", "An extra container port X-aws-proxy-port may route to (repeatable). 8080, Hooks.Port and the image's EXPOSE ports are always routable.").argParser(parseProxyPort)).addOption(new Option("--auto-resume", "Resume a suspended MicroVM on its next request instead of answering 503 (autoResumeEnabled).")).addOption(new Option("--no-build-cache", "Build the image with docker build --no-cache.")).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"MicrovmImageLogicalId\":{\"KEY\":\"VALUE\"}, \"Parameters\": {...}})")).addOption(new Option("--timeout <ms>", "Default deadline in milliseconds for each hook without its own <Hook>TimeoutInSeconds (/terminate defaults to 10000), and for the app to answer HTTP when there is no /ready hook. Default 60000.").default(6e4).argParser(parseTimeoutMs)).addOption(new Option("--assume-role <arn>", "Assume this role (the MicroVM's execution role, a run-microvm parameter rather than part of the template) and forward STS-issued temp credentials to the containers. Off by default: the shell credentials are forwarded.")).addOption(emulateRoleViaOption("--assume-role")).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Read a deployed CloudFormation stack and substitute Ref / Fn::ImportValue in env vars with the deployed physical IDs / exports. Bare form uses the resolved stack name.")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-cfn-stack as the CFn client region."));
|
|
27015
27179
|
}
|
|
27016
27180
|
|
|
27017
27181
|
//#endregion
|
|
@@ -32359,4 +32523,4 @@ function addStudioSpecificOptions(cmd) {
|
|
|
32359
32523
|
|
|
32360
32524
|
//#endregion
|
|
32361
32525
|
export { postHook as $, withoutKeys as $a, probeHostGatewaySupport as $i, addImageOverrideOptions as $n, resolveApiTargetSubset as $r, classifyS3Error as $t, microvmFidelityWarnings as A, filterWebSocketApisByIdentifiers as Aa, translateLambdaResponse as Ai, stripCloudFrontImport as An, A2A_CONTAINER_PORT as Ar, readContainerLogTail as At, MICROVM_WS_BASE_PROTOCOL as B, AGENTCORE_RUNTIME_TYPE as Ba, ConnectionRegistry as Bi, createLocalStartAlbCommand as Bn, AGENTCORE_SESSION_ID_HEADER as Br, parseWebFunctionBuildConfig as Bt, addListSpecificOptions as C, resolveWatchConfig as Ca, attachAuthorizers as Ci, WEB_FUNCTION_REVISION_TYPE as Cn, setShadowReadyTimeoutMs as Cr, parseKvsFileOverrides as Ct, buildMicrovmLambdaView as D, availableWebSocketApiIdentifiers as Da, isFunctionUrlOacFronted as Di, compileCloudFrontFunction as Dn, createLocalInvokeAgentCoreCommand as Dr, WEB_FUNCTION_CONTAINER_PORT as Dt, addStartMicrovmSpecificOptions as E, listTargets as Ea, buildCorsConfigFromCloudFrontChain as Ei, resolveWebFunctionTarget as En, addInvokeAgentCoreSpecificOptions as Er, RecentOutput as Et, microvmImageTag as F, resolveLambdaArnIntrinsic as Fa, pickResponseTemplate as Fi, findFileAssetForObjectKey as Fn, MCP_PROTOCOL_VERSION as Fr, buildNodeEntryFileStart as Ft, startMicrovmFrontDoor as G, DynamicReferenceResolver as Ga, buildDisconnectEvent as Gi, addStartServiceSpecificOptions as Gn, SUPPORTED_CODE_RUNTIMES as Gr, readWebFunctionServiceConfig as Gt, PROXY_PORT_HEADER as H, pickAgentCoreCandidateStack as Ha, handleConnectionsRequest as Hi, resolveAlbTarget as Hn, waitForAgentCoreHttpReady as Hr, WEB_FUNCTION_HTTP_ENDPOINT_ENV as Ht, planMicrovmPorts as I, AGENTCORE_A2A_PROTOCOL as Ia, selectIntegrationResponse as Ii, isBucketDeploymentResource as In, mcpInvokeOnce as Ir, defaultWebFunctionPlatform as It, MICROVM_HOOK_PATH_PREFIX as J, firstUsableRegion as Ja, createFileWatcher as Ji, addRunTaskSpecificOptions as Jn, renderCodeDockerfile as Jr, idFromArn as Jt, stripMicrovmProxyHeaders as K, containsDynamicReference as Ka, buildMessageEvent as Ki, createLocalStartServiceCommand as Kn, buildAgentCoreCodeImage as Kr, webFunctionAssumeRole as Kt, readExposedPorts as L, AGENTCORE_AGUI_PROTOCOL as La, tryParseStatus as Li, resolveBucketDeploymentObjectKey as Ln, parseSseForJsonRpc as Lr, resolveWebFunctionRuntime as Lt, DEFAULT_TERMINATE_HOOK_TIMEOUT_MS as M, webSocketApiMatchesIdentifier as Ma, buildHttpApiV2Event as Mi, createLocalFileKvsDataSource as Mn, a2aInvokeOnce as Mr, waitForWebFunctionReady as Mt, LocalMicrovm as N, discoverRoutes as Na, buildRestV1Event as Ni, createUnboundCloudFrontModule as Nn, MCP_CONTAINER_PORT as Nr, watchContainerExit as Nt, createLocalStartMicrovmCommand as O, discoverWebSocketApis as Oa, matchPreflight as Oi, runViewerRequest as On, bridgeAgentCoreWs as Or, containerFailure as Ot, buildMicrovmImage as P, pickRefLogicalId as Pa, evaluateResponseParameters as Pi, bucketDeploymentSourceObjectKeys as Pn, MCP_PATH as Pr, WEB_FUNCTION_RUNTIMES as Pt, pollBuildHook as Q, resolveDynamicReferencesInEnv as Qa, HOST_GATEWAY_MIN_VERSION as Qi, addEcsAssumeRoleOptions as Qn, createWatchPredicates as Qr, resolveDeployedOriginBucket as Qt, setContainerPaused as R, AGENTCORE_HTTP_PROTOCOL as Ra, VtlEvaluationError as Ri, addAlbSpecificOptions as Rn, AGENTCORE_SIGV4_SERVICE as Rr, supportedWebFunctionRuntimes as Rt, StudioEventBus as S, resolveSsmParameters as Sa, invokeTokenAuthorizer as Si, WEB_FUNCTION_ENDPOINT_TYPE as Sn, SOFT_RELOAD_COMPLETION_LOG_SUFFIX as Sr, normalizeKvsFileKeys as St, formatTargetListing as T, countTargets as Ta, buildCorsConfigByApiId as Ti, WebFunctionResolutionError as Tn, attachContainerLogStreamer as Tr, resolveCloudFrontTarget as Tt, rewriteUpgradeResponseHead as U, resolveAgentCoreTarget as Ua, parseConnectionsPath as Ui, isApplicationLoadBalancer as Un, waitForAgentCorePing as Ur, buildWebFunctionLambdaView as Ut, MicrovmStateError as V, AgentCoreResolutionError as Va, buildMgmtEndpointEnvUrl as Vi, parseLbPortOverrides as Vn, invokeAgentCore as Vr, resolveWebFunctionArtifact as Vt, selectTargetPort as W, DynamicReferenceResolutionError as Wa, buildConnectEvent as Wi, resolveAlbFrontDoor as Wn, downloadAndExtractS3Bundle as Wr, finalizeWebFunctionEnv as Wt, callRuntimeHook as X, keysOverriddenBy as Xa, createLocalInvokeCommand as Xi, MAX_TASKS_SUBNET_RANGE_CAP as Xn, addStartApiSpecificOptions as Xr, createDeployedKvsDataSource as Xt, MicrovmHookError as Y, keysNotFromTemplate as Ya, addInvokeSpecificOptions as Yi, createLocalRunTaskCommand as Yn, toCmdArgv as Yr, resolveKvsModulesForDistribution as Yt, generateMicrovmId as Z, parseDynamicReference as Za, HOST_DOCKER_INTERNAL_GATEWAY as Zi, addCommonEcsServiceOptions as Zn, createLocalStartApiCommand as Zr, resolveDeployedKvsArnByName as Zt, filterStudioTargetGroups as _, resolveCfnFallbackRegion as _a, verifyJwtViaDiscovery as _i, pickKvsLogicalIdFromArn as _n, isLocalCdkAssetImage as _r, attachAgentCoreWsBridge as _t, createLocalStudioCommand as a, assertEcsTaskImagesResolvable as aa, filterRoutesByApiIdentifiers as ai, serveLambdaUrlOrigin as an, resolveSharedSidecarCredentials as ar, disposeMicrovmCodeArtifact as at, renderStudioHtml as b, CfnLocalStateProvider as ba, evaluateCachedLambdaPolicy as bi, pickWebFunctionEndpointLogicalIdFromOrigin as bn, CloudMapRegistry as br, addStartCloudFrontSpecificOptions as bt, startStudioProxy as c, substituteEnvVarsFromState as ca, startApiServer as ci, buildEdgeRequestEvent as cn, buildImageOverrideTag as cr, resolveMicrovmImageTarget as ct, createStudioDispatcher as d, LocalStateSourceError as da, defaultCredentialsLoader as di, httpHeadersToEdge as dn, mergeForService as dr, createLocalStartWebFunctionCommand as dt, resolveHostGatewayExtraHosts as ea, createAuthorizerCache as ei, createS3OriginReader as en, addAwsEndpointOptions as eo, buildEcsImageResolutionContext$1 as er, runHookBody as et, filterStudioCustomResources as f, UNNAMED_WORKLOAD as fa, buildCognitoJwksUrl as fi, CLOUDFRONT_DISTRIBUTION_TYPE as fn, parseImageOverrideFlags as fr, addStartAgentCoreSpecificOptions as ft, annotatePinnedEcsTargets as g, rejectExplicitCfnStackWithMultipleStacks as ga, verifyJwtAuthorizer as gi, pickFunctionUrlLogicalIdFromOrigin as gn, imageOverrideKeyAliases as gr, startAgentCoreHttpServer as gt, annotateEcsTaskPinnedTargets as h, isCfnFlagPresent as ha, verifyCognitoJwt as hi, isCloudFrontDistribution as hn, describePinnedImageUri as hr, selectServeInboundAuth as ht, coerceStopRequest as i, EcsTaskResolutionError as ia, filterRoutesByApiIdentifier as ii, serveFromStaticOrigin as in, resolveEcsAssumeRoleOption as ir, MicrovmResolutionError as it, readRunHookPayload as j, parseSelectionExpressionPath as ja, applyAuthorizerOverlay as ji, createCloudFrontModule as jn, A2A_PATH as jr, startWebFunctionContainer as jt, finalizeMicrovmEnv as k, discoverWebSocketApisOrThrow as ka, matchRoute as ki, runViewerResponse as kn, invokeAgentCoreWs as kr, planWebFunctionContainer as kt, relayServeRequest as l, substituteEnvVarsFromStateAsync as la, resolveSelectionExpression as li, buildEdgeResponseEvent as ln, canonicalizeImageOverrideKeys as lr, s3KeyOfUri as lt, annotateAlbPinnedBackingServices as m, groupWorkloadsRoutedApart as ma, createJwksCache as mi, extractKvsAssociations as mn, runImageOverrideBuilds as mr, buildAgentCoreServeAuthCheck as mt, coerceRunRequest as n, resolveRuntimeFileExtension as na, buildStageMap as ni, startCloudFrontServer as nn, parseMaxTasks as nr, MICROVM_DEFAULT_INGRESS_PORT as nt, resolveServeBaseUrl as o, substituteAgainstState as oa, groupRoutesByServer as oi, applyEdgeRequestResult as on, runEcsServiceEmulator as or, readMicrovmImageConfig as ot, isCustomResourceLambdaTarget as p, createLocalStateProvider as pa, buildJwksUrlFromIssuer as pi, describeS3OriginDomain as pn, resolveImageOverrides as pr, createLocalStartAgentCoreCommand as pt, MAX_RUN_HOOK_PAYLOAD_BYTES as q, deployedFillMayBeSecret as qa, classifySourceChange as qi, serviceStrategy as qn, computeCodeImageTag as qr, webFunctionFidelityWarnings as qt, coerceServeRequest as r, resolveRuntimeImage as ra, availableApiIdentifiers as ri, resolveErrorResponseCandidates as rn, parseRestartPolicy as rr, MICROVM_IMAGE_TYPE as rt, createStudioServeManager as s, substituteAgainstStateAsync as sa, readMtlsMaterialsFromDisk as si, applyEdgeResponseResult as sn, ImageOverrideError as sr, resolveMicrovmCodeArtifact as st, addStudioSpecificOptions as t, resolveRuntimeCodeMountPath as ta, attachStageContext as ti, matchBehavior as tn, awsEndpointOptions as to, ecsClusterOption as tr, waitForAppAnswer as tt, reinvoke as u, materializeLayerFromArn as ua, resolveServiceIntegrationParameters as ui, edgeHeadersToHttp as un, enforceImageOverrideOrphans as ur, addStartWebFunctionSpecificOptions as ut, startStudioServer as v, resolveCfnRegion as va, buildMethodArn as vi, pickLambdaEdgeFunctionLogicalId as vn, listPinnedTargets as vr, startAgentCoreWsBridge as vt, createLocalListCommand as w, resolveSingleTarget as wa, applyCorsResponseHeaders as wi, WEB_FUNCTION_TYPE as wn, getContainerNetworkIp as wr, parseOriginOverrides as wt, createStudioStore as x, collectSsmParameterRefs as xa, invokeRequestAuthorizer as xi, resolveCloudFrontDistribution as xn, DEFAULT_SHADOW_READY_TIMEOUT_MS as xr, createLocalStartCloudFrontCommand as xt, toStudioTargetGroups as y, resolveCfnStackName as ya, computeRequestIdentityHash as yi, pickTargetFunctionLogicalId as yn, buildCloudMapIndex as yr, LocalStartCloudFrontError as yt, MICROVM_CONTROL_PATH as z, AGENTCORE_MCP_PROTOCOL as za, bufferToBody as zi, albStrategy as zn, signAgentCoreInvocation as zr, disposeWebFunctionArtifact as zt };
|
|
32362
|
-
//# sourceMappingURL=local-studio-
|
|
32526
|
+
//# sourceMappingURL=local-studio-PpZpeKYn.js.map
|