cdk-local 0.7.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +2 -2
- package/dist/index.d.ts +47 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/{local-start-service-Bh1z2yKs.js → local-start-service-Rit5YxNR.js} +47 -36
- package/dist/{local-start-service-Bh1z2yKs.js.map → local-start-service-Rit5YxNR.js.map} +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { i as
|
|
2
|
+
import { i as createLocalStartApiCommand, r as createLocalRunTaskCommand, t as createLocalStartServiceCommand, u as createLocalInvokeCommand } from "./local-start-service-Rit5YxNR.js";
|
|
3
3
|
import { Command } from "commander";
|
|
4
4
|
|
|
5
5
|
//#region src/cli/index.ts
|
|
6
6
|
const program = new Command();
|
|
7
|
-
program.name("cdkl").description("Run AWS CDK stacks locally with Docker.").version("0.
|
|
7
|
+
program.name("cdkl").description("Run AWS CDK stacks locally with Docker.").version("0.9.0");
|
|
8
8
|
program.addCommand(createLocalInvokeCommand());
|
|
9
9
|
program.addCommand(createLocalStartApiCommand());
|
|
10
10
|
program.addCommand(createLocalRunTaskCommand());
|
package/dist/index.d.ts
CHANGED
|
@@ -123,5 +123,51 @@ declare class CfnLocalStateProvider implements LocalStateProvider {
|
|
|
123
123
|
dispose(): void;
|
|
124
124
|
}
|
|
125
125
|
//#endregion
|
|
126
|
-
|
|
126
|
+
//#region src/local/intrinsic-utils.d.ts
|
|
127
|
+
declare function pickRefLogicalId(value: unknown): string | null;
|
|
128
|
+
//#endregion
|
|
129
|
+
//#region src/local/intrinsic-lambda-arn.d.ts
|
|
130
|
+
type LambdaArnResolveOutcome = {
|
|
131
|
+
kind: 'resolved';
|
|
132
|
+
logicalId: string;
|
|
133
|
+
} | {
|
|
134
|
+
kind: 'unsupported';
|
|
135
|
+
detail: string;
|
|
136
|
+
};
|
|
137
|
+
declare function resolveLambdaArnIntrinsic(value: unknown): LambdaArnResolveOutcome;
|
|
138
|
+
//#endregion
|
|
139
|
+
//#region src/local/parameter-mapping.d.ts
|
|
140
|
+
interface RequestParameterContext {
|
|
141
|
+
headers: Readonly<Record<string, string>>;
|
|
142
|
+
queryString: Readonly<Record<string, string>>;
|
|
143
|
+
pathParameters: Readonly<Record<string, string>>;
|
|
144
|
+
requestPath: string;
|
|
145
|
+
body: string;
|
|
146
|
+
context: Readonly<Record<string, string>>;
|
|
147
|
+
stageVariables: Readonly<Record<string, string>>;
|
|
148
|
+
authorizer?: Readonly<Record<string, unknown>>;
|
|
149
|
+
}
|
|
150
|
+
type ResolveParametersOutcome = {
|
|
151
|
+
kind: 'ok';
|
|
152
|
+
resolved: Record<string, string>;
|
|
153
|
+
} | {
|
|
154
|
+
kind: 'error';
|
|
155
|
+
reason: string;
|
|
156
|
+
};
|
|
157
|
+
declare function resolveServiceIntegrationParameters(parameters: Readonly<Record<string, unknown>>, ctx: RequestParameterContext): ResolveParametersOutcome;
|
|
158
|
+
declare function resolveSelectionExpression(input: string, ctx: RequestParameterContext): string;
|
|
159
|
+
//#endregion
|
|
160
|
+
//#region src/local/api-gateway-response.d.ts
|
|
161
|
+
interface TranslatedHttpResponse {
|
|
162
|
+
statusCode: number;
|
|
163
|
+
headers: Record<string, string>;
|
|
164
|
+
cookies: string[];
|
|
165
|
+
body: Buffer;
|
|
166
|
+
}
|
|
167
|
+
declare function translateLambdaResponse(payload: unknown, version: 'v1' | 'v2'): TranslatedHttpResponse;
|
|
168
|
+
//#endregion
|
|
169
|
+
//#region src/local/docker-inspect.d.ts
|
|
170
|
+
declare function getContainerNetworkIp(containerId: string, networkName: string): Promise<string | undefined>;
|
|
171
|
+
//#endregion
|
|
172
|
+
export { type CdkLocalEmbedConfig, CfnLocalStateProvider, type CfnLocalStateProviderOptions, type CreateLocalInvokeCommandOptions, type CreateLocalRunTaskCommandOptions, type CreateLocalStartApiCommandOptions, type CreateLocalStartServiceCommandOptions, type CrossStackResolver, type ExtraStateProviders, type LambdaArnResolveOutcome, type LocalStateProvider, type LocalStateProviderFactory, type LocalStateRecord, LocalStateSourceError, type LocalStateSourceOptions, type RequestParameterContext, type ResolveParametersOutcome, type SubstitutionContext, type TranslatedHttpResponse, createLocalInvokeCommand, createLocalRunTaskCommand, createLocalStartApiCommand, createLocalStartServiceCommand, createLocalStateProvider, getContainerNetworkIp, isCfnFlagPresent, pickRefLogicalId, rejectExplicitCfnStackWithMultipleStacks, resolveCfnRegion, resolveCfnStackName, resolveLambdaArnIntrinsic, resolveSelectionExpression, resolveServiceIntegrationParameters, translateLambdaResponse };
|
|
127
173
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types/state.ts","../src/local/state-resolver.ts","../src/local/local-state-provider.ts","../src/cli/commands/local-state-source.ts","../src/local/embed-config.ts","../src/cli/commands/local-invoke.ts","../src/cli/commands/local-start-api.ts","../src/cli/commands/local-run-task.ts","../src/cli/commands/local-start-service.ts","../src/local/cfn-local-state-provider.ts"],"mappings":";;;;UAuLiB,aAAA;EAEf,UAAA;EAGA,YAAA;EAGA,UAAA,EAAY,MAAA;EAcZ,kBAAA,GAAqB,MAAA;EAGrB,UAAA,GAAa,MAAA;EAGb,YAAA;EAGA,QAAA,GAAW,MAAA;EAmBX,cAAA;EAMA,mBAAA;EAyBA,aAAA;AAAA;;;UCxIe,gBAAA;EACf,SAAA;EACA,MAAA;EACA,SAAA;EACA,SAAA;AAAA;AAAA,UAqBe,kBAAA;EAOf,aAAA,CAAc,UAAA,WAAqB,OAAA;EAQnC,qBAAA,CACE,aAAA,UACA,cAAA,UACA,UAAA,WACC,OAAA;AAAA;AAAA,UAGY,mBAAA;EAEf,SAAA,EAAW,MAAA,SAAe,aAAA;EAE1B,gBAAA,GAAmB,gBAAA;EAOnB,kBAAA,GAAqB,kBAAA;EAOrB,cAAA;AAAA;;;UCrJe,gBAAA;EAQf,SAAA,EAAW,MAAA,SAAe,aAAA;EAO1B,OAAA,EAAS,MAAA;EAOT,MAAA;AAAA;AAAA,UAsBe,kBAAA;EAAA,SAMN,KAAA;EAQT,IAAA,CAAK,SAAA,UAAmB,WAAA,uBAAkC,OAAA,CAAQ,gBAAA;EAalE,uBAAA,CAAwB,cAAA,WAAyB,OAAA,CAAQ,kBAAA;EAKzD,OAAA;AAAA;;;UC9Ee,uBAAA;EAOf,YAAA;EAEA,MAAA;EAEA,OAAA;EAMA,WAAA;EAAA,CAEC,GAAA;AAAA;AAAA,KAQS,yBAAA,IAA6B,OAAA,EAAS,uBAAA,KAA4B,kBAAA;AAAA,KAUlE,mBAAA,GAAsB,MAAA,SAAe,yBAAA;AAAA,iBAUjC,mBAAA,CAAoB,YAAA,oBAAgC,SAAA;AAAA,iBAapD,gBAAA,CAAiB,IAAA,EAAM,IAAA,CAAK,uBAAA;AAAA,iBAgB5B,gBAAA,CACd,OAAA,EAAS,IAAA,CAAK,uBAAA,6BACd,WAAA;AAAA,cAqBW,qBAAA,SAA8B,KAAA;cAC7B,OAAA;AAAA;AAAA,iBAkBE,wCAAA,CACd,OAAA,EAAS,IAAA,CAAK,uBAAA,mBACd,gBAAA;AAAA,iBAiCc,wBAAA,CACd,OAAA,EAAS,uBAAA,EACT,SAAA,UACA,WAAA,sBACA,mBAAA,GAAsB,mBAAA,GACrB,kBAAA;;;UCtLc,mBAAA;EAMf,OAAA;EAOA,UAAA;EAMA,WAAA;EAOA,kBAAA;EAMA,gBAAA;EAMA,SAAA;AAAA;;;UC8Ee,+BAAA;EACf,mBAAA,GAAsB,mBAAA;EAEtB,WAAA,GAAc,mBAAA;AAAA;AAAA,iBA22BA,wBAAA,CAAyB,IAAA,GAAM,+BAAA,GAAuC,OAAA;;;UCzvBrE,iCAAA;EACf,mBAAA,GAAsB,mBAAA;EAEtB,WAAA,GAAc,mBAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types/state.ts","../src/local/state-resolver.ts","../src/local/local-state-provider.ts","../src/cli/commands/local-state-source.ts","../src/local/embed-config.ts","../src/cli/commands/local-invoke.ts","../src/cli/commands/local-start-api.ts","../src/cli/commands/local-run-task.ts","../src/cli/commands/local-start-service.ts","../src/local/cfn-local-state-provider.ts","../src/local/intrinsic-utils.ts","../src/local/intrinsic-lambda-arn.ts","../src/local/parameter-mapping.ts","../src/local/api-gateway-response.ts","../src/local/docker-inspect.ts"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { _ as CfnLocalStateProvider, a as resolveSelectionExpression, c as pickRefLogicalId, d as LocalStateSourceError, f as createLocalStateProvider, g as resolveCfnStackName, h as resolveCfnRegion, i as createLocalStartApiCommand, l as resolveLambdaArnIntrinsic, m as rejectExplicitCfnStackWithMultipleStacks, n as getContainerNetworkIp, o as resolveServiceIntegrationParameters, p as isCfnFlagPresent, r as createLocalRunTaskCommand, s as translateLambdaResponse, t as createLocalStartServiceCommand, u as createLocalInvokeCommand } from "./local-start-service-Rit5YxNR.js";
|
|
2
2
|
|
|
3
|
-
export { CfnLocalStateProvider, LocalStateSourceError, createLocalInvokeCommand, createLocalRunTaskCommand, createLocalStartApiCommand, createLocalStartServiceCommand, createLocalStateProvider, isCfnFlagPresent, rejectExplicitCfnStackWithMultipleStacks, resolveCfnRegion, resolveCfnStackName };
|
|
3
|
+
export { CfnLocalStateProvider, LocalStateSourceError, createLocalInvokeCommand, createLocalRunTaskCommand, createLocalStartApiCommand, createLocalStartServiceCommand, createLocalStateProvider, getContainerNetworkIp, isCfnFlagPresent, pickRefLogicalId, rejectExplicitCfnStackWithMultipleStacks, resolveCfnRegion, resolveCfnStackName, resolveLambdaArnIntrinsic, resolveSelectionExpression, resolveServiceIntegrationParameters, translateLambdaResponse };
|
|
@@ -10736,9 +10736,8 @@ function buildCorsConfigFromCloudFrontChain(template) {
|
|
|
10736
10736
|
* its own SigV4 credentials (service `lambda`) via the OAC, and the Function
|
|
10737
10737
|
* URL's auto-generated resource policy trusts `cloudfront.amazonaws.com`.
|
|
10738
10738
|
* Locally there is no CloudFront in the path, so no client signature can
|
|
10739
|
-
* reproduce CloudFront's. Callers use this to
|
|
10740
|
-
*
|
|
10741
|
-
* `--allow-unverified-sigv4`.
|
|
10739
|
+
* reproduce CloudFront's. Callers use this to keep these Function URLs in
|
|
10740
|
+
* warn-and-pass mode even when `--strict-sigv4` is set.
|
|
10742
10741
|
*
|
|
10743
10742
|
* Detection: a CloudFront origin whose `DomainName` matches the canonical
|
|
10744
10743
|
* `Fn::GetAtt[<fnUrlLogicalId>, 'FunctionUrl']` chain (see
|
|
@@ -12148,17 +12147,29 @@ function base64UrlDecodeToBuffer(input) {
|
|
|
12148
12147
|
* invalid.
|
|
12149
12148
|
*
|
|
12150
12149
|
* When the request's `Credential=AKID/...` scope names a different
|
|
12151
|
-
* access-key-id than the one the dev has locally
|
|
12152
|
-
*
|
|
12153
|
-
*
|
|
12154
|
-
*
|
|
12155
|
-
*
|
|
12156
|
-
*
|
|
12157
|
-
*
|
|
12158
|
-
*
|
|
12159
|
-
*
|
|
12160
|
-
*
|
|
12161
|
-
*
|
|
12150
|
+
* access-key-id than the one the dev has locally (or no local credentials
|
|
12151
|
+
* resolve at all), we therefore **warn-and-pass by default**: allow + a
|
|
12152
|
+
* one-line warn + an obviously-fake principalId
|
|
12153
|
+
* (`unverified-foreign-identity` / `unverified-no-creds`). Local execution
|
|
12154
|
+
* is overwhelmingly used to exercise app logic and ergonomics, not to
|
|
12155
|
+
* reproduce an authorization boundary cdk-local cannot fully emulate
|
|
12156
|
+
* anyway — so blocking the most common legitimate case (federated /
|
|
12157
|
+
* Cognito Identity Pool / cross-account signers, which are foreign by
|
|
12158
|
+
* construction) is the wrong default. The fake principalId keeps
|
|
12159
|
+
* identity-based handler authz from silently trusting a forged caller, and
|
|
12160
|
+
* the deployed API Gateway still does the real verification + IAM
|
|
12161
|
+
* evaluation.
|
|
12162
|
+
*
|
|
12163
|
+
* The opt-in **`--strict-sigv4`** flag flips this to **fail-closed**: deny
|
|
12164
|
+
* unverifiable requests. Use it when you want local enforcement to mirror a
|
|
12165
|
+
* verified-identity assumption. OAC-fronted Function URLs always
|
|
12166
|
+
* warn-and-pass regardless of `--strict-sigv4` (CloudFront re-signs the
|
|
12167
|
+
* origin request in production, so no local client signature exists to
|
|
12168
|
+
* verify) and their warn lines reference CloudFront OAC.
|
|
12169
|
+
*
|
|
12170
|
+
* Genuinely missing / malformed signatures (no Authorization header,
|
|
12171
|
+
* unparseable header, wrong algorithm, stale date) **are** rejected in both
|
|
12172
|
+
* modes — those would never reach the deployed API either.
|
|
12162
12173
|
*
|
|
12163
12174
|
* # NOT IN SCOPE
|
|
12164
12175
|
*
|
|
@@ -12206,17 +12217,17 @@ function defaultCredentialsLoader() {
|
|
|
12206
12217
|
* http-server maps this to 401 (REST v1 `missing-identity`).
|
|
12207
12218
|
* - **Signature mismatch** under the dev's own credentials → `{allow: false}`.
|
|
12208
12219
|
* The http-server maps this to 403 (REST v1 `policy-deny`).
|
|
12209
|
-
* - **Different `Credential` access-key-id than the dev has**
|
|
12210
|
-
* `{allow:
|
|
12211
|
-
*
|
|
12212
|
-
*
|
|
12213
|
-
* (warn-and-pass).
|
|
12220
|
+
* - **Different `Credential` access-key-id than the dev has** (or no
|
|
12221
|
+
* local creds resolve) → unverifiable. `{allow: true}` plus a one-line
|
|
12222
|
+
* warn + fake principalId by default (warn-and-pass). With `strict`
|
|
12223
|
+
* (the `--strict-sigv4` flag) → `{allow: false}` (fail-closed).
|
|
12214
12224
|
* - **Valid signature with the dev's credentials** → `{allow: true}`.
|
|
12215
12225
|
* The principal id surfaced to the handler is the parsed
|
|
12216
12226
|
* `Credential` access-key-id.
|
|
12217
|
-
* - **`oacFronted` route** →
|
|
12218
|
-
*
|
|
12219
|
-
*
|
|
12227
|
+
* - **`oacFronted` route** → foreign / no-creds requests always pass
|
|
12228
|
+
* through regardless of `strict` (CloudFront re-signs origin requests
|
|
12229
|
+
* in production, so no local client signature can be verified) and the
|
|
12230
|
+
* warn lines reference CloudFront OAC.
|
|
12220
12231
|
*/
|
|
12221
12232
|
async function verifySigV4(req, loadCredentials, opts = {}) {
|
|
12222
12233
|
const logger = getLogger();
|
|
@@ -12276,14 +12287,14 @@ async function verifySigV4(req, loadCredentials, opts = {}) {
|
|
|
12276
12287
|
local = await loadCredentials();
|
|
12277
12288
|
} catch (err) {
|
|
12278
12289
|
const reason = err instanceof Error ? err.message : String(err);
|
|
12279
|
-
if (!opts.
|
|
12280
|
-
logger.warn(`AWS_IAM authorizer: could not resolve local AWS credentials (${reason}), so the request's SigV4 signature cannot be verified
|
|
12290
|
+
if (opts.strict && !opts.oacFronted) {
|
|
12291
|
+
logger.warn(`AWS_IAM authorizer: could not resolve local AWS credentials (${reason}), so the request's SigV4 signature cannot be verified. --strict-sigv4 is set, so cdk-local denies unverifiable IAM requests; remove --strict-sigv4 to warn-and-pass (the default), or configure AWS credentials cdk-local can read.`);
|
|
12281
12292
|
return {
|
|
12282
12293
|
allow: false,
|
|
12283
12294
|
identityHash: void 0
|
|
12284
12295
|
};
|
|
12285
12296
|
}
|
|
12286
|
-
logger.warn(opts.oacFronted ? `AWS_IAM authorizer: Function URL is fronted by CloudFront OAC (CloudFront re-signs origin requests in production), and local AWS credentials could not be resolved (${reason}). Passing through with unverified principalId 'unverified-no-creds'. Do NOT trust event.requestContext.identity.accessKey in handler code.` : `AWS_IAM authorizer:
|
|
12297
|
+
logger.warn(opts.oacFronted ? `AWS_IAM authorizer: Function URL is fronted by CloudFront OAC (CloudFront re-signs origin requests in production), and local AWS credentials could not be resolved (${reason}). Passing through with unverified principalId 'unverified-no-creds'. Do NOT trust event.requestContext.identity.accessKey in handler code.` : `AWS_IAM authorizer: could not resolve local AWS credentials (${reason}), so the request's SigV4 signature cannot be verified locally (SigV4 is an HMAC shared-secret signature; the deployed API Gateway verifies it against AWS's copy of the secret). Passing through with unverified principalId 'unverified-no-creds' — cdk-local's default for unverifiable IAM requests; pass --strict-sigv4 to deny instead. Do NOT trust event.requestContext.identity.accessKey in handler code.`);
|
|
12287
12298
|
return {
|
|
12288
12299
|
allow: true,
|
|
12289
12300
|
principalId: "unverified-no-creds",
|
|
@@ -12293,9 +12304,9 @@ async function verifySigV4(req, loadCredentials, opts = {}) {
|
|
|
12293
12304
|
if (local.accessKeyId.toLowerCase() !== parsed.credentialAccessKeyId.toLowerCase()) {
|
|
12294
12305
|
const warned = opts.warnedForeignIds;
|
|
12295
12306
|
const dedupKey = parsed.credentialAccessKeyId.toLowerCase();
|
|
12296
|
-
if (!opts.
|
|
12307
|
+
if (opts.strict && !opts.oacFronted) {
|
|
12297
12308
|
if (!warned || !warned.has(dedupKey)) {
|
|
12298
|
-
logger.warn(`AWS_IAM authorizer: request signed with access-key-id '${parsed.credentialAccessKeyId}', which differs from the AWS credentials cdk-local resolved locally
|
|
12309
|
+
logger.warn(`AWS_IAM authorizer: request signed with access-key-id '${parsed.credentialAccessKeyId}', which differs from the AWS credentials cdk-local resolved locally — SigV4 (HMAC / shared-secret) can only be verified with the signer's own credentials, never a federated / Cognito Identity Pool / cross-account signer's. --strict-sigv4 is set, so cdk-local denies it; remove --strict-sigv4 to warn-and-pass (the default), or sign the request with the same credentials cdk-local resolves locally.`);
|
|
12299
12310
|
warned?.add(dedupKey);
|
|
12300
12311
|
}
|
|
12301
12312
|
return {
|
|
@@ -12304,7 +12315,7 @@ async function verifySigV4(req, loadCredentials, opts = {}) {
|
|
|
12304
12315
|
};
|
|
12305
12316
|
}
|
|
12306
12317
|
if (!warned || !warned.has(dedupKey)) {
|
|
12307
|
-
logger.warn(opts.oacFronted ? `AWS_IAM authorizer: Function URL is fronted by CloudFront OAC — in production CloudFront re-signs the origin request, so the local client's signature (access-key-id '${parsed.credentialAccessKeyId}') cannot be verified. Passing through with unverified principalId 'unverified-foreign-identity'. Do NOT trust event.requestContext.authorizer.principalId in handler code.` : `AWS_IAM authorizer: request signed with
|
|
12318
|
+
logger.warn(opts.oacFronted ? `AWS_IAM authorizer: Function URL is fronted by CloudFront OAC — in production CloudFront re-signs the origin request, so the local client's signature (access-key-id '${parsed.credentialAccessKeyId}') cannot be verified. Passing through with unverified principalId 'unverified-foreign-identity'. Do NOT trust event.requestContext.authorizer.principalId in handler code.` : `AWS_IAM authorizer: request signed with access-key-id '${parsed.credentialAccessKeyId}', a federated / Cognito Identity Pool / cross-account signer cdk-local cannot verify locally (SigV4 is an HMAC shared-secret signature; the deployed API Gateway verifies it because AWS holds the secret). Passing through with unverified principalId 'unverified-foreign-identity' — cdk-local's default for unverifiable IAM requests; pass --strict-sigv4 to deny instead. Do NOT trust event.requestContext.authorizer.principalId in handler code.`);
|
|
12308
12319
|
warned?.add(dedupKey);
|
|
12309
12320
|
}
|
|
12310
12321
|
return {
|
|
@@ -13275,7 +13286,7 @@ async function runAuthorizerPass(authorizer, snapshot, matchCtx, state, opts, re
|
|
|
13275
13286
|
body: snapshot.body
|
|
13276
13287
|
}, opts.sigV4CredentialsLoader, {
|
|
13277
13288
|
...opts.sigV4WarnedForeignIds && { warnedForeignIds: opts.sigV4WarnedForeignIds },
|
|
13278
|
-
|
|
13289
|
+
strict: opts.sigV4Strict === true,
|
|
13279
13290
|
...oacFronted && { oacFronted: true }
|
|
13280
13291
|
});
|
|
13281
13292
|
if (!sigResult.allow) return {
|
|
@@ -14420,7 +14431,7 @@ async function localStartApiCommand(target, options, extraStateProviders) {
|
|
|
14420
14431
|
jwksWarnedUrls,
|
|
14421
14432
|
sigV4CredentialsLoader,
|
|
14422
14433
|
sigV4WarnedForeignIds,
|
|
14423
|
-
|
|
14434
|
+
sigV4Strict: options.strictSigv4 === true,
|
|
14424
14435
|
...defaultRegion && { defaultRegion }
|
|
14425
14436
|
});
|
|
14426
14437
|
servers.push({
|
|
@@ -14466,7 +14477,7 @@ async function localStartApiCommand(target, options, extraStateProviders) {
|
|
|
14466
14477
|
jwksCache,
|
|
14467
14478
|
jwksWarnedUrls,
|
|
14468
14479
|
sigV4WarnedForeignIds,
|
|
14469
|
-
|
|
14480
|
+
sigV4Strict: options.strictSigv4 === true,
|
|
14470
14481
|
preDispatch: async (req, res) => {
|
|
14471
14482
|
if (!registryRef) return false;
|
|
14472
14483
|
return handleManagementRequest(req, res, registryRef.registry);
|
|
@@ -14829,11 +14840,11 @@ function warnIamRoutes(routesWithAuth) {
|
|
|
14829
14840
|
}
|
|
14830
14841
|
if (iamRoutes.length === 0 && oacRoutes.length === 0) return false;
|
|
14831
14842
|
if (iamRoutes.length > 0) {
|
|
14832
|
-
logger.warn(`${iamRoutes.length} route(s) declare AuthorizationType: AWS_IAM — ${getEmbedConfig().cliName} start-api verifies SigV4 signatures
|
|
14843
|
+
logger.warn(`${iamRoutes.length} route(s) declare AuthorizationType: AWS_IAM — ${getEmbedConfig().cliName} start-api verifies the SigV4 signatures it CAN (requests signed with your local AWS credentials), but cannot verify a federated / Cognito Identity Pool / cross-account signer and does NOT emulate IAM policy evaluation (resource / action / condition rules). By default such unverifiable requests warn-and-pass with a placeholder principalId — pass --strict-sigv4 to deny them instead. Downstream authorization is the dev's responsibility.`);
|
|
14833
14844
|
for (const declaredAt of iamRoutes) logger.warn(` - ${declaredAt}`);
|
|
14834
14845
|
}
|
|
14835
14846
|
if (oacRoutes.length > 0) {
|
|
14836
|
-
logger.warn(`${oacRoutes.length} Function URL route(s) with AuthType: AWS_IAM are fronted by a CloudFront Origin Access Control. In production CloudFront re-signs the origin request, so no local client signature can be verified — ${getEmbedConfig().cliName} start-api passes these through (warn-and-pass)
|
|
14847
|
+
logger.warn(`${oacRoutes.length} Function URL route(s) with AuthType: AWS_IAM are fronted by a CloudFront Origin Access Control. In production CloudFront re-signs the origin request, so no local client signature can be verified — ${getEmbedConfig().cliName} start-api passes these through (warn-and-pass) and they ignore --strict-sigv4. Do NOT trust the request identity in handler code.`);
|
|
14837
14848
|
for (const declaredAt of oacRoutes) logger.warn(` - ${declaredAt}`);
|
|
14838
14849
|
}
|
|
14839
14850
|
return true;
|
|
@@ -15727,7 +15738,7 @@ function resolveMtlsConfig(options) {
|
|
|
15727
15738
|
*/
|
|
15728
15739
|
function createLocalStartApiCommand(opts = {}) {
|
|
15729
15740
|
setEmbedConfig(opts.embedConfig);
|
|
15730
|
-
const startApi = new Command("start-api").description("Run a long-running local HTTP server that maps API Gateway routes (REST v1, HTTP API, Function URL) to Lambda invocations against the AWS Lambda Runtime Interface Emulator (Docker required). Supports Lambda TOKEN/REQUEST authorizers, Cognito User Pool / HTTP v2 JWT authorizers, and AWS_IAM auth (REST v1 `AuthorizationType: AWS_IAM` and Function URL `AuthType: AWS_IAM` — SigV4 signature verification only; IAM policy evaluation is NOT emulated). When JWKS is unreachable, JWT authorizers fall back to pass-through (every token accepted) with a warn line — local dev fallback. VPC-config Lambdas run locally and surface a warn line at startup; their containers do NOT get attached to the deployed VPC subnets, so calls to private RDS / ElastiCache will fail.").argument("[target]", `Optional API filter. Accepts the bare CDK logical id ('MyHttpApi'; single-stack apps only), stack-qualified logical id ('MyStack:MyHttpApi'), full CDK Construct path ('MyStack/MyHttpApi/Resource'), or an ancestor Construct path that prefix-matches ('MyStack/MyHttpApi'). When omitted, every discovered API gets its own server. Mirrors \`${getEmbedConfig().cliName} invoke\` / \`${getEmbedConfig().cliName} run-task\` target syntax.`).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, --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("--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("--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. Bare <arn> = global default; <LogicalId>=<arn> = per-Lambda override (repeatable). Per-Lambda > global > unset (developer creds passed through).").argParser((raw, prev) => parseAssumeRoleToken(raw, prev))).addOption(new Option("--watch", "Hot-reload: re-synth + re-discover routes when cdk.out/ or asset directories change. 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 <target> argument instead. 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("--
|
|
15741
|
+
const startApi = new Command("start-api").description("Run a long-running local HTTP server that maps API Gateway routes (REST v1, HTTP API, Function URL) to Lambda invocations against the AWS Lambda Runtime Interface Emulator (Docker required). Supports Lambda TOKEN/REQUEST authorizers, Cognito User Pool / HTTP v2 JWT authorizers, and AWS_IAM auth (REST v1 `AuthorizationType: AWS_IAM` and Function URL `AuthType: AWS_IAM` — SigV4 signature verification only; IAM policy evaluation is NOT emulated). When JWKS is unreachable, JWT authorizers fall back to pass-through (every token accepted) with a warn line — local dev fallback. VPC-config Lambdas run locally and surface a warn line at startup; their containers do NOT get attached to the deployed VPC subnets, so calls to private RDS / ElastiCache will fail.").argument("[target]", `Optional API filter. Accepts the bare CDK logical id ('MyHttpApi'; single-stack apps only), stack-qualified logical id ('MyStack:MyHttpApi'), full CDK Construct path ('MyStack/MyHttpApi/Resource'), or an ancestor Construct path that prefix-matches ('MyStack/MyHttpApi'). When omitted, every discovered API gets its own server. Mirrors \`${getEmbedConfig().cliName} invoke\` / \`${getEmbedConfig().cliName} run-task\` target syntax.`).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, --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("--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("--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. Bare <arn> = global default; <LogicalId>=<arn> = per-Lambda override (repeatable). Per-Lambda > global > unset (developer creds passed through).").argParser((raw, prev) => parseAssumeRoleToken(raw, prev))).addOption(new Option("--watch", "Hot-reload: re-synth + re-discover routes when cdk.out/ or asset directories change. 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 <target> argument instead. 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)).action(withErrorHandling(async (target, options) => {
|
|
15731
15742
|
await localStartApiCommand(target, options, opts.extraStateProviders);
|
|
15732
15743
|
}));
|
|
15733
15744
|
[
|
|
@@ -18293,5 +18304,5 @@ function createLocalStartServiceCommand(opts = {}) {
|
|
|
18293
18304
|
}
|
|
18294
18305
|
|
|
18295
18306
|
//#endregion
|
|
18296
|
-
export {
|
|
18297
|
-
//# sourceMappingURL=local-start-service-
|
|
18307
|
+
export { CfnLocalStateProvider as _, resolveSelectionExpression as a, pickRefLogicalId as c, LocalStateSourceError as d, createLocalStateProvider as f, resolveCfnStackName as g, resolveCfnRegion as h, createLocalStartApiCommand as i, resolveLambdaArnIntrinsic as l, rejectExplicitCfnStackWithMultipleStacks as m, getContainerNetworkIp as n, resolveServiceIntegrationParameters as o, isCfnFlagPresent as p, createLocalRunTaskCommand as r, translateLambdaResponse as s, createLocalStartServiceCommand as t, createLocalInvokeCommand as u };
|
|
18308
|
+
//# sourceMappingURL=local-start-service-Rit5YxNR.js.map
|