@venturekit/infra 0.0.0-dev.20260514025219 → 0.0.0-dev.20260515022321

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.
Files changed (49) hide show
  1. package/dist/cdk/app-stack.d.ts +330 -0
  2. package/dist/cdk/app-stack.d.ts.map +1 -0
  3. package/dist/cdk/app-stack.js +875 -0
  4. package/dist/cdk/app-stack.js.map +1 -0
  5. package/dist/cdk/config-stack.d.ts +104 -0
  6. package/dist/cdk/config-stack.d.ts.map +1 -0
  7. package/dist/cdk/config-stack.js +161 -0
  8. package/dist/cdk/config-stack.js.map +1 -0
  9. package/dist/cdk/data-stack.d.ts +198 -0
  10. package/dist/cdk/data-stack.d.ts.map +1 -0
  11. package/dist/cdk/data-stack.js +511 -0
  12. package/dist/cdk/data-stack.js.map +1 -0
  13. package/dist/cdk/edge-stack.d.ts +91 -0
  14. package/dist/cdk/edge-stack.d.ts.map +1 -0
  15. package/dist/cdk/edge-stack.js +364 -0
  16. package/dist/cdk/edge-stack.js.map +1 -0
  17. package/dist/cdk/identity-stack.d.ts +98 -0
  18. package/dist/cdk/identity-stack.d.ts.map +1 -0
  19. package/dist/cdk/identity-stack.js +254 -0
  20. package/dist/cdk/identity-stack.js.map +1 -0
  21. package/dist/cdk/index.d.ts +16 -0
  22. package/dist/cdk/index.d.ts.map +1 -1
  23. package/dist/cdk/index.js +17 -0
  24. package/dist/cdk/index.js.map +1 -1
  25. package/dist/cdk/messaging-stack.d.ts +109 -0
  26. package/dist/cdk/messaging-stack.d.ts.map +1 -0
  27. package/dist/cdk/messaging-stack.js +320 -0
  28. package/dist/cdk/messaging-stack.js.map +1 -0
  29. package/dist/cdk/network-stack.d.ts +87 -0
  30. package/dist/cdk/network-stack.d.ts.map +1 -0
  31. package/dist/cdk/network-stack.js +265 -0
  32. package/dist/cdk/network-stack.js.map +1 -0
  33. package/dist/cdk/shared/cross-stack-refs.d.ts +278 -0
  34. package/dist/cdk/shared/cross-stack-refs.d.ts.map +1 -0
  35. package/dist/cdk/shared/cross-stack-refs.js +326 -0
  36. package/dist/cdk/shared/cross-stack-refs.js.map +1 -0
  37. package/dist/cdk/shared/lambda-helpers.d.ts +82 -0
  38. package/dist/cdk/shared/lambda-helpers.d.ts.map +1 -0
  39. package/dist/cdk/shared/lambda-helpers.js +201 -0
  40. package/dist/cdk/shared/lambda-helpers.js.map +1 -0
  41. package/dist/cdk/shared/ssm-keys.d.ts +460 -0
  42. package/dist/cdk/shared/ssm-keys.d.ts.map +1 -0
  43. package/dist/cdk/shared/ssm-keys.js +291 -0
  44. package/dist/cdk/shared/ssm-keys.js.map +1 -0
  45. package/dist/cdk/stack.d.ts +3 -11
  46. package/dist/cdk/stack.d.ts.map +1 -1
  47. package/dist/cdk/stack.js +184 -41
  48. package/dist/cdk/stack.js.map +1 -1
  49. package/package.json +2 -2
@@ -0,0 +1,364 @@
1
+ /**
2
+ * Tier 5 — Edge stack.
3
+ *
4
+ * Owns the public-facing entry surface:
5
+ *
6
+ * - The `AWS::ApiGatewayV2::Api` (HttpApi) shell with stable
7
+ * ID + access logging configured. Routes (which target Lambdas)
8
+ * are added in the app stack via `HttpApi.fromHttpApiAttributes`
9
+ * + `addRoutes()`.
10
+ * - Custom domain(s) per `domains[]` intent: ACM certificate
11
+ * (existing ARN, Route53-validated, or DNS-validation-pending),
12
+ * `AWS::ApiGatewayV2::DomainName`, `ApiMapping` to the API's
13
+ * default stage, optional Route53 alias.
14
+ * - CloudFront distribution(s) over imported S3 buckets per
15
+ * `storage[]` intent that has `cdn: true`. Bucket lives in the
16
+ * data stack; distribution + Origin Access Control + alias DNS
17
+ * live here. The OAC's `aws:SourceArn`-scoped bucket policy
18
+ * statement is added to the imported `IBucket` automatically by
19
+ * `S3BucketOrigin.withOriginAccessControl(...)`.
20
+ *
21
+ * # Lifecycle position
22
+ *
23
+ * Updated occasionally (~quarterly): a new domain, a new CDN, an
24
+ * ACM cert rotation. The HttpApi ID itself is the most fragile:
25
+ * the `*.execute-api.{region}.amazonaws.com` URL embeds it, and
26
+ * mobile apps shipped with that URL baked in cannot be patched
27
+ * without a full update cycle. RETAIN under strict is therefore
28
+ * not just durability — it's external-contract preservation.
29
+ *
30
+ * # Public surface (via SSM)
31
+ *
32
+ * - `edgeKeys.apiId / apiEndpoint / apiCustomDomain /
33
+ * apiDefaultStageName` — the app stack reads these to import
34
+ * the API and add its discovered routes.
35
+ * - `edgeKeys.storageCdnDomain(storageId) /
36
+ * storageCdnDistributionId(storageId)` per CDN-fronted bucket.
37
+ *
38
+ * # What this stack does NOT do
39
+ *
40
+ * - **No routes / integrations.** `HttpApi.addRoutes(...)` runs
41
+ * in the app stack. CDK's `HttpApi.fromHttpApiAttributes` returns
42
+ * an `IHttpApi` that supports `addRoutes`, so the cross-stack
43
+ * pattern is the same as the in-stack one.
44
+ *
45
+ * - **No Lambda permissions.** API Gateway invoking a Lambda
46
+ * requires a `lambda:InvokeFunction` resource policy on the
47
+ * Lambda granted to `apigateway.amazonaws.com` with `aws:SourceArn`
48
+ * scoping. CDK's `HttpLambdaIntegration` adds that grant
49
+ * automatically when the route is created — which happens in the
50
+ * app stack.
51
+ *
52
+ * - **No CloudFront-Lambda@Edge wiring.** Edge Lambdas (request /
53
+ * response viewer functions) are extreme-rare in the VentureKit
54
+ * surface. If they're added later, they'd live here because their
55
+ * lifecycle is tied to the distribution, not to a single regional
56
+ * handler.
57
+ */
58
+ import * as cdk from 'aws-cdk-lib';
59
+ import * as apigatewayv2 from 'aws-cdk-lib/aws-apigatewayv2';
60
+ import * as acm from 'aws-cdk-lib/aws-certificatemanager';
61
+ import * as route53 from 'aws-cdk-lib/aws-route53';
62
+ import * as route53Targets from 'aws-cdk-lib/aws-route53-targets';
63
+ import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
64
+ import * as cloudfrontOrigins from 'aws-cdk-lib/aws-cloudfront-origins';
65
+ import * as s3 from 'aws-cdk-lib/aws-s3';
66
+ import * as logs from 'aws-cdk-lib/aws-logs';
67
+ import { DATA_SAFETY_CONFIG } from '@venturekit/core';
68
+ import { writeSsm } from './shared/cross-stack-refs.js';
69
+ import { edgeKeys } from './shared/ssm-keys.js';
70
+ function toLogRetention(days) {
71
+ if (days <= 1)
72
+ return logs.RetentionDays.ONE_DAY;
73
+ if (days <= 7)
74
+ return logs.RetentionDays.ONE_WEEK;
75
+ if (days <= 14)
76
+ return logs.RetentionDays.TWO_WEEKS;
77
+ if (days <= 30)
78
+ return logs.RetentionDays.ONE_MONTH;
79
+ if (days <= 90)
80
+ return logs.RetentionDays.THREE_MONTHS;
81
+ if (days <= 180)
82
+ return logs.RetentionDays.SIX_MONTHS;
83
+ if (days <= 365)
84
+ return logs.RetentionDays.ONE_YEAR;
85
+ return logs.RetentionDays.INFINITE;
86
+ }
87
+ export class VentureEdgeStack extends cdk.Stack {
88
+ api;
89
+ distributions = new Map();
90
+ isStrictRetain;
91
+ constructor(scope, id, props) {
92
+ super(scope, id, props);
93
+ const { projectName, stage, envConfig, infrastructure, storageBuckets } = props;
94
+ this.isStrictRetain =
95
+ DATA_SAFETY_CONFIG[envConfig.dataSafety].removalPolicy === 'retain';
96
+ const apiConfig = envConfig.api;
97
+ const obsConfig = envConfig.observability;
98
+ // ─── HttpApi shell ──────────────────────────────────────────
99
+ // Created with NO routes — routes live in the app stack.
100
+ // CORS preflight, throttling, and access logging are all
101
+ // edge-tier concerns and stay here.
102
+ this.api = new apigatewayv2.HttpApi(this, 'Api', {
103
+ apiName: `${projectName}-${stage}`,
104
+ corsPreflight: apiConfig.cors
105
+ ? {
106
+ allowOrigins: apiConfig.cors.allowOrigins,
107
+ allowMethods: apiConfig.cors.allowMethods.map((m) => apigatewayv2.CorsHttpMethod[m.toUpperCase()] ??
108
+ apigatewayv2.CorsHttpMethod.ANY),
109
+ allowHeaders: apiConfig.cors.allowHeaders,
110
+ allowCredentials: apiConfig.cors.allowCredentials,
111
+ maxAge: cdk.Duration.seconds(apiConfig.cors.maxAgeSec),
112
+ }
113
+ : {
114
+ allowOrigins: ['*'],
115
+ allowMethods: [
116
+ apigatewayv2.CorsHttpMethod.GET,
117
+ apigatewayv2.CorsHttpMethod.POST,
118
+ apigatewayv2.CorsHttpMethod.PUT,
119
+ apigatewayv2.CorsHttpMethod.DELETE,
120
+ apigatewayv2.CorsHttpMethod.PATCH,
121
+ apigatewayv2.CorsHttpMethod.OPTIONS,
122
+ ],
123
+ allowHeaders: ['*'],
124
+ },
125
+ disableExecuteApiEndpoint: false,
126
+ });
127
+ if (this.isStrictRetain) {
128
+ // The `*.execute-api.{region}.amazonaws.com` URL embeds the
129
+ // API ID. Mobile apps shipped with that URL baked in cannot
130
+ // be patched without a full update cycle. RETAIN keeps the
131
+ // API ID stable across accidental stack deletes.
132
+ const cfnApi = this.api.node.defaultChild;
133
+ cfnApi.cfnOptions.deletionPolicy = cdk.CfnDeletionPolicy.RETAIN;
134
+ cfnApi.cfnOptions.updateReplacePolicy = cdk.CfnDeletionPolicy.RETAIN;
135
+ }
136
+ // ─── Access logging on the default stage ─────────────────────
137
+ const apiLogGroup = new logs.LogGroup(this, 'ApiAccessLog', {
138
+ logGroupName: `/venturekit/${projectName}/${stage}/api-access`,
139
+ retention: toLogRetention(obsConfig.logs.retentionDays),
140
+ removalPolicy: this.isStrictRetain
141
+ ? cdk.RemovalPolicy.RETAIN
142
+ : cdk.RemovalPolicy.DESTROY,
143
+ });
144
+ const defaultStage = this.api.defaultStage?.node.defaultChild;
145
+ if (defaultStage) {
146
+ defaultStage.accessLogSettings = {
147
+ destinationArn: apiLogGroup.logGroupArn,
148
+ // Compact JSON access-log format. Operators ingest these
149
+ // straight into CloudWatch Insights or stream to S3.
150
+ format: JSON.stringify({
151
+ requestId: '$context.requestId',
152
+ ip: '$context.identity.sourceIp',
153
+ method: '$context.httpMethod',
154
+ path: '$context.path',
155
+ status: '$context.status',
156
+ latency: '$context.responseLatency',
157
+ userAgent: '$context.identity.userAgent',
158
+ }),
159
+ };
160
+ }
161
+ // ─── Public surface ─────────────────────────────────────────
162
+ writeSsm(this, edgeKeys.apiId(projectName, stage), this.api.apiId, {
163
+ description: `HttpApi ID — app stack imports via fromHttpApiAttributes.`,
164
+ });
165
+ writeSsm(this, edgeKeys.apiEndpoint(projectName, stage), this.api.apiEndpoint, { description: `HttpApi default endpoint URL.` });
166
+ writeSsm(this, edgeKeys.apiDefaultStageName(projectName, stage),
167
+ // HttpApi always uses `$default`. Publishing it explicitly
168
+ // means future named-stage support doesn't break consumers.
169
+ '$default', { description: `HttpApi default stage name.` });
170
+ // ─── Custom domains ─────────────────────────────────────────
171
+ if (infrastructure.domains) {
172
+ // VentureKit currently supports a single primary custom
173
+ // domain — multi-domain projects map them all onto the same
174
+ // API. We publish only the FIRST domain under
175
+ // `apiCustomDomain` (the canonical one app code reads).
176
+ let primaryDomain;
177
+ for (const intent of infrastructure.domains) {
178
+ this.createDomain(intent, projectName, stage);
179
+ if (!primaryDomain)
180
+ primaryDomain = intent.domain;
181
+ }
182
+ if (primaryDomain) {
183
+ writeSsm(this, edgeKeys.apiCustomDomain(projectName, stage), primaryDomain, {
184
+ description: `Primary custom domain. App code building OAuth redirect ` +
185
+ `URIs / webhook URLs should prefer this when set.`,
186
+ });
187
+ }
188
+ }
189
+ // ─── CloudFront over storage buckets ────────────────────────
190
+ if (infrastructure.storage) {
191
+ for (const intent of infrastructure.storage) {
192
+ if (intent.cdn !== true)
193
+ continue;
194
+ if (!storageBuckets) {
195
+ throw new Error(`[venturekit] edge stack: storage intent '${intent.id}' has cdn=true ` +
196
+ `but storageBuckets was not passed. The CLI generator ` +
197
+ `must wire dataStack.buckets.get('${intent.id}').bucket into ` +
198
+ `VentureEdgeStackProps.storageBuckets.`);
199
+ }
200
+ const bucket = storageBuckets.get(intent.id);
201
+ if (!bucket) {
202
+ throw new Error(`[venturekit] edge stack: storage intent '${intent.id}' has cdn=true ` +
203
+ `but no bucket was passed in storageBuckets. The CLI generator ` +
204
+ `must wire dataStack.buckets.get('${intent.id}').bucket into ` +
205
+ `VentureEdgeStackProps.storageBuckets.`);
206
+ }
207
+ this.createStorageCdn(intent, projectName, stage, bucket);
208
+ }
209
+ }
210
+ }
211
+ createDomain(intent, projectName, stage) {
212
+ const resourceName = `${projectName}-${intent.id}`;
213
+ // Three certificate paths:
214
+ // 1. Operator pre-issued an ACM cert: pass the ARN.
215
+ // 2. We own the Route53 zone: auto-issue with DNS validation.
216
+ // 3. Neither: create the cert without DNS validation — it
217
+ // will sit in PENDING until the operator publishes the
218
+ // validation CNAMEs from the AWS console.
219
+ let certificate;
220
+ if (intent.certificateArn) {
221
+ certificate = acm.Certificate.fromCertificateArn(this, `${resourceName}-cert`, intent.certificateArn);
222
+ }
223
+ else if (intent.hostedZoneId) {
224
+ const hostedZone = route53.HostedZone.fromHostedZoneAttributes(this, `${resourceName}-zone`, {
225
+ hostedZoneId: intent.hostedZoneId,
226
+ // `intent.domain` may be `api.example.com` (apex zone is
227
+ // `example.com`). Take the trailing two labels for the zone
228
+ // name — Route53 doesn't accept a subdomain here.
229
+ zoneName: intent.domain.split('.').slice(-2).join('.'),
230
+ });
231
+ certificate = new acm.Certificate(this, `${resourceName}-cert`, {
232
+ domainName: intent.domain,
233
+ validation: acm.CertificateValidation.fromDns(hostedZone),
234
+ });
235
+ }
236
+ else {
237
+ certificate = new acm.Certificate(this, `${resourceName}-cert`, {
238
+ domainName: intent.domain,
239
+ });
240
+ }
241
+ const domainName = new apigatewayv2.DomainName(this, `${resourceName}-domain`, {
242
+ domainName: intent.domain,
243
+ certificate,
244
+ });
245
+ if (this.isStrictRetain) {
246
+ // The custom domain is the public contract with the world;
247
+ // deleting it forces DNS reconfiguration on every client /
248
+ // integration. RETAIN keeps it claimed to this AWS account
249
+ // for `cdk import` recovery.
250
+ const cfnDomain = domainName.node.defaultChild;
251
+ cfnDomain.cfnOptions.deletionPolicy = cdk.CfnDeletionPolicy.RETAIN;
252
+ cfnDomain.cfnOptions.updateReplacePolicy = cdk.CfnDeletionPolicy.RETAIN;
253
+ }
254
+ // API mapping — what binds the custom domain to the API's
255
+ // default stage. Mappings re-create cleanly so RETAIN here is
256
+ // just a recovery convenience.
257
+ const apiMapping = new apigatewayv2.ApiMapping(this, `${resourceName}-mapping`, {
258
+ api: this.api,
259
+ domainName,
260
+ stage: this.api.defaultStage,
261
+ });
262
+ if (this.isStrictRetain) {
263
+ const cfnMapping = apiMapping.node.defaultChild;
264
+ cfnMapping.cfnOptions.deletionPolicy = cdk.CfnDeletionPolicy.RETAIN;
265
+ cfnMapping.cfnOptions.updateReplacePolicy = cdk.CfnDeletionPolicy.RETAIN;
266
+ }
267
+ // Route53 alias when we own the zone.
268
+ if (intent.hostedZoneId) {
269
+ const hostedZone = route53.HostedZone.fromHostedZoneAttributes(this, `${resourceName}-zone-record`, {
270
+ hostedZoneId: intent.hostedZoneId,
271
+ zoneName: intent.domain.split('.').slice(-2).join('.'),
272
+ });
273
+ new route53.ARecord(this, `${resourceName}-a-record`, {
274
+ zone: hostedZone,
275
+ recordName: intent.domain,
276
+ target: route53.RecordTarget.fromAlias(new route53Targets.ApiGatewayv2DomainProperties(domainName.regionalDomainName, domainName.regionalHostedZoneId)),
277
+ });
278
+ }
279
+ }
280
+ createStorageCdn(intent, projectName, stage, bucket) {
281
+ const logicalId = `storage-${intent.id}-cdn`;
282
+ // Optional alternate domain (CNAME) + ACM cert. CloudFront only
283
+ // accepts certs from us-east-1 regardless of which region the
284
+ // rest of the stack runs in.
285
+ //
286
+ // vk cert request --domain cdn.example.com --region us-east-1
287
+ //
288
+ // Empty `cdnCertificateArn` is the same "pending" sentinel as
289
+ // `DomainIntent.certificateArn`: skip the alias and let the
290
+ // distribution serve at its `*.cloudfront.net` hostname until
291
+ // the next deploy.
292
+ const aliasReady = typeof intent.cdnDomain === 'string' &&
293
+ intent.cdnDomain.length > 0 &&
294
+ typeof intent.cdnCertificateArn === 'string' &&
295
+ intent.cdnCertificateArn.length > 0;
296
+ let aliasProps = {};
297
+ if (aliasReady) {
298
+ aliasProps = {
299
+ domainNames: [intent.cdnDomain],
300
+ certificate: acm.Certificate.fromCertificateArn(this, `${logicalId}-cert`, intent.cdnCertificateArn),
301
+ };
302
+ }
303
+ // Re-import the bucket as a *purely-attribute-based* IBucket so
304
+ // CDK's `S3BucketOrigin.withOriginAccessControl` does NOT call
305
+ // `addToResourcePolicy` on the original bucket construct. The
306
+ // policy that authorizes CloudFront-OAC reads is created by the
307
+ // data stack (see `VentureDataStack.createStorage` — `intent.cdn`
308
+ // branch). If we let `withOriginAccessControl` plumb the policy
309
+ // automatically here, CDK would add both a `data → edge` (policy
310
+ // wants the distribution ARN) and an `edge → data` (origin wants
311
+ // the bucket regional domain) cross-stack dependency, producing
312
+ // a synth-time cycle.
313
+ const importedBucket = s3.Bucket.fromBucketAttributes(this, `${logicalId}-imported-bucket`, {
314
+ bucketName: bucket.bucketName,
315
+ bucketRegionalDomainName: bucket.bucketRegionalDomainName,
316
+ });
317
+ const distribution = new cloudfront.Distribution(this, logicalId, {
318
+ comment: `${projectName}-${intent.id}-${stage}`,
319
+ defaultBehavior: {
320
+ // OAC mode: CloudFront accesses S3 via the service principal
321
+ // with an `aws:SourceAccount`-scoped bucket policy pinned at
322
+ // the data tier. Anonymous direct-S3 GETs stay forbidden;
323
+ // only the CDN's signed CloudFront request can read the
324
+ // object.
325
+ origin: cloudfrontOrigins.S3BucketOrigin.withOriginAccessControl(importedBucket),
326
+ viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
327
+ allowedMethods: cloudfront.AllowedMethods.ALLOW_GET_HEAD_OPTIONS,
328
+ cachedMethods: cloudfront.CachedMethods.CACHE_GET_HEAD_OPTIONS,
329
+ cachePolicy: cloudfront.CachePolicy.CACHING_OPTIMIZED,
330
+ compress: true,
331
+ },
332
+ // PriceClass 100 = US/Canada/Europe edges only. Cheaper than
333
+ // the global default for projects whose audience matches.
334
+ priceClass: cloudfront.PriceClass.PRICE_CLASS_100,
335
+ enabled: true,
336
+ ...aliasProps,
337
+ });
338
+ if (this.isStrictRetain) {
339
+ // Distributions take 15-30 minutes to roll out globally;
340
+ // their `*.cloudfront.net` hostname is often cached by
341
+ // upstream consumers. RETAIN keeps the distribution in place
342
+ // for `cdk import` recovery.
343
+ const cfn = distribution.node.defaultChild;
344
+ cfn.cfnOptions.deletionPolicy = cdk.CfnDeletionPolicy.RETAIN;
345
+ cfn.cfnOptions.updateReplacePolicy = cdk.CfnDeletionPolicy.RETAIN;
346
+ }
347
+ this.distributions.set(intent.id, distribution);
348
+ // The published `cdn-domain` is either the alias (when
349
+ // configured + cert is ready) or the bare CloudFront hostname.
350
+ // Consumers building public URLs must read this rather than
351
+ // hardcoding either one.
352
+ const publishedDomain = aliasReady
353
+ ? intent.cdnDomain
354
+ : distribution.distributionDomainName;
355
+ writeSsm(this, edgeKeys.storageCdnDomain(projectName, stage, intent.id), publishedDomain, {
356
+ description: `CDN domain for storage '${intent.id}' — public URL host.`,
357
+ });
358
+ writeSsm(this, edgeKeys.storageCdnDistributionId(projectName, stage, intent.id), distribution.distributionId, {
359
+ description: `CloudFront distribution ID — for CreateInvalidation calls ` +
360
+ `from app-stack handlers after content rewrites.`,
361
+ });
362
+ }
363
+ }
364
+ //# sourceMappingURL=edge-stack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edge-stack.js","sourceRoot":"","sources":["../../src/cdk/edge-stack.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Tier 2 — Identity stack.
3
+ *
4
+ * Owns:
5
+ * - Cognito User Pool(s) — one per declared `auth` intent
6
+ * - App Client(s) per pool (`auth.clients[]`, defaulting to one
7
+ * `'default'` client when omitted)
8
+ * - Federated provider Secrets Manager placeholder(s) holding
9
+ * `{clientId, clientSecret}` for Google / Apple / Meta /
10
+ * other OAuth providers declared in `auth.federated[]`
11
+ *
12
+ * # Lifecycle position
13
+ *
14
+ * Updated rarely (~quarterly): MFA toggle, password-policy bump,
15
+ * new federated provider, occasional new app client. Survives stack
16
+ * delete because losing a User Pool means losing every user
17
+ * identity + password hash — by far the most catastrophic
18
+ * recoverable state in a VentureKit deploy. Both `DeletionPolicy:
19
+ * Retain` AND Cognito's native `deletionProtection` flag must be
20
+ * flipped before the pool can be deleted, and every flip is
21
+ * CloudTrail-logged.
22
+ *
23
+ * # Public surface (via SSM)
24
+ *
25
+ * - `identityKeys.userPoolId(authId)` — the Cognito pool ID
26
+ * - `identityKeys.userPoolArn(authId)` — for IAM grant scoping
27
+ * in the app stack
28
+ * - `identityKeys.appClientId(authId)` — first declared client
29
+ * (the canonical one app code reads)
30
+ * - `identityKeys.federatedSecretArn(authId, provider)` per
31
+ * provider in `auth.federated[]`
32
+ *
33
+ * # What this stack does NOT do
34
+ *
35
+ * - **No IAM grants.** Lambdas need
36
+ * `cognito-idp:AdminCreateUser` / `AdminInitiateAuth` /
37
+ * `AdminConfirmSignUp` etc. on the pool, and `secretsmanager:Get
38
+ * SecretValue` on each federated provider Secret. Those grants
39
+ * produce `AWS::IAM::Policy` resources attached to the
40
+ * shared-Lambda-role — which lives in the app stack. The app
41
+ * stack imports the pool ARN + secret ARNs via SSM and applies
42
+ * the grants there.
43
+ *
44
+ * - **No env-var injection.** The legacy single-stack code
45
+ * side-effected `this.ventureBaseEnv['COGNITO_USER_POOL_ID'] =
46
+ * userPool.userPoolId` to broadcast the pool ID into every
47
+ * Lambda's environment at synth time. Cross-stack, the app
48
+ * stack pulls the pool ID via `readSsmString` and injects it
49
+ * into Lambda env-vars itself — same broadcast, lock-free.
50
+ *
51
+ * - **No Cognito Hosted UI / IdP wiring.** VentureKit deliberately
52
+ * doesn't enable Cognito's Hosted UI or wire the federated
53
+ * providers as Cognito Identity Providers. Your app owns the
54
+ * login screen; the SPA does the OAuth dance with the IdP
55
+ * directly and posts the resulting tokens to your API.
56
+ * `signInAsFederatedUser` from `@venturekit/auth/server`
57
+ * verifies them and mints Cognito session tokens via
58
+ * `AdminInitiateAuth` — which is why the federated providers
59
+ * need `ALLOW_ADMIN_USER_PASSWORD_AUTH` enabled on the app
60
+ * client below.
61
+ */
62
+ import * as cdk from 'aws-cdk-lib';
63
+ import * as cognito from 'aws-cdk-lib/aws-cognito';
64
+ import * as secretsmanager from 'aws-cdk-lib/aws-secretsmanager';
65
+ import { Construct } from 'constructs';
66
+ import { type EnvConfig, type VentureIntent } from '@venturekit/core';
67
+ export interface VentureIdentityStackProps extends cdk.StackProps {
68
+ /** Project name — feeds resource names + SSM keys. */
69
+ projectName: string;
70
+ /** Stage. */
71
+ stage: string;
72
+ /** Fully-resolved environment config. */
73
+ envConfig: EnvConfig;
74
+ /**
75
+ * Infrastructure intent. Read for `auth[]`. All other slices are
76
+ * ignored.
77
+ */
78
+ infrastructure: VentureIntent;
79
+ }
80
+ export declare class VentureIdentityStack extends cdk.Stack {
81
+ /**
82
+ * In-process accessors for sibling stacks (the app stack reads
83
+ * the pool reference for IAM grants when deployed in the same
84
+ * `cdk.App`). Keyed by `auth.id`.
85
+ */
86
+ readonly userPools: Map<string, cognito.UserPool>;
87
+ readonly appClients: Map<string, cognito.UserPoolClient>;
88
+ /**
89
+ * Federated provider secrets, keyed by `${authId}:${provider}`.
90
+ * Order-stable for tests; the actual app stack consumer reads via
91
+ * SSM rather than this in-memory map.
92
+ */
93
+ readonly federatedSecrets: Map<string, secretsmanager.Secret>;
94
+ private readonly isStrictRetain;
95
+ constructor(scope: Construct, id: string, props: VentureIdentityStackProps);
96
+ private createAuth;
97
+ }
98
+ //# sourceMappingURL=identity-stack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity-stack.d.ts","sourceRoot":"","sources":["../../src/cdk/identity-stack.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AAEH,OAAO,KAAK,GAAG,MAAM,aAAa,CAAC;AACnC,OAAO,KAAK,OAAO,MAAM,yBAAyB,CAAC;AACnD,OAAO,KAAK,cAAc,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAsB,KAAK,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAI1F,MAAM,WAAW,yBAA0B,SAAQ,GAAG,CAAC,UAAU;IAC/D,sDAAsD;IACtD,WAAW,EAAE,MAAM,CAAC;IAEpB,aAAa;IACb,KAAK,EAAE,MAAM,CAAC;IAEd,yCAAyC;IACzC,SAAS,EAAE,SAAS,CAAC;IAErB;;;OAGG;IACH,cAAc,EAAE,aAAa,CAAC;CAC/B;AAED,qBAAa,oBAAqB,SAAQ,GAAG,CAAC,KAAK;IACjD;;;;OAIG;IACH,SAAgB,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAa;IAErE,SAAgB,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,CAAa;IAE5E;;;;OAIG;IACH,SAAgB,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,MAAM,CAAC,CAAa;IAEjF,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAU;gBAE7B,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,yBAAyB;IAY1E,OAAO,CAAC,UAAU;CA8LnB"}