@friggframework/devtools 2.0.0-next.36 → 2.0.0-next.38

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.
@@ -54,7 +54,7 @@ describe('Generate Command', () => {
54
54
  // Mock app definition
55
55
  jest.doMock(mockAppDefinitionPath, () => ({
56
56
  vpc: { enable: true },
57
- encryption: { useDefaultKMSForFieldLevelEncryption: true },
57
+ encryption: { fieldLevelEncryptionMethod: 'kms' },
58
58
  ssm: { enable: true },
59
59
  websockets: { enable: false }
60
60
  }), { virtual: true });
@@ -228,7 +228,7 @@ async function generateCommand(options = {}) {
228
228
  function analyzeAppFeatures(appDefinition) {
229
229
  const features = {
230
230
  vpc: appDefinition.vpc?.enable === true,
231
- kms: appDefinition.encryption?.useDefaultKMSForFieldLevelEncryption === true,
231
+ kms: appDefinition.encryption?.fieldLevelEncryptionMethod === 'kms',
232
232
  ssm: appDefinition.ssm?.enable === true,
233
233
  websockets: appDefinition.websockets?.enable === true,
234
234
  // Add more feature detection as needed
@@ -670,7 +670,7 @@ To integrate Frigg into your production application:
670
670
  const appDefinition = {
671
671
  integrations: [], // Will be populated based on selected integrations
672
672
  user: { password: true },
673
- encryption: { useDefaultKMSForFieldLevelEncryption: true },
673
+ encryption: { fieldLevelEncryptionMethod: 'kms' },
674
674
  vpc: { enable: true },
675
675
  security: {
676
676
  cors: {
@@ -9,7 +9,7 @@ AWS Discovery automatically finds your default AWS resources (VPC, subnets, secu
9
9
  AWS Discovery runs automatically during `frigg build` and `frigg deploy` when your AppDefinition includes:
10
10
 
11
11
  - `vpc.enable: true` - VPC support
12
- - `encryption.useDefaultKMSForFieldLevelEncryption: true` - KMS encryption
12
+ - `encryption.fieldLevelEncryptionMethod: 'kms'` - KMS encryption
13
13
  - `ssm.enable: true` - SSM Parameter Store
14
14
 
15
15
  ## Fail-Fast Behavior
@@ -222,7 +222,7 @@ If you're stuck, try this recovery process:
222
222
  // backend/index.js - temporarily disable problematic features
223
223
  const appDefinition = {
224
224
  vpc: { enable: false },
225
- encryption: { useDefaultKMSForFieldLevelEncryption: false },
225
+ encryption: { fieldLevelEncryptionMethod: 'aes' },
226
226
  ssm: { enable: false }
227
227
  };
228
228
  ```
@@ -354,7 +354,7 @@ Additional permissions needed when your app definition includes `vpc: { enable:
354
354
 
355
355
  ### KMS Support
356
356
 
357
- Additional permissions needed when your app definition includes `encryption: { useDefaultKMSForFieldLevelEncryption: true }`:
357
+ Additional permissions needed when your app definition includes `encryption: { fieldLevelEncryptionMethod: 'kms' }`:
358
358
 
359
359
  ```json
360
360
  {
@@ -58,7 +58,7 @@ The command analyzes your `backend/index.js` AppDefinition and generates IAM pol
58
58
  - Route table and security group management
59
59
  - Elastic IP allocation
60
60
 
61
- #### KMS Encryption (`encryption.useDefaultKMSForFieldLevelEncryption: true`)
61
+ #### KMS Encryption (`encryption.fieldLevelEncryptionMethod: 'kms'`)
62
62
 
63
63
  - KMS key usage for Lambda and S3
64
64
  - Data encryption and decryption permissions
@@ -85,7 +85,7 @@ const appDefinition = {
85
85
  enable: true,
86
86
  },
87
87
  encryption: {
88
- useDefaultKMSForFieldLevelEncryption: true,
88
+ fieldLevelEncryptionMethod: 'kms',
89
89
  },
90
90
  ssm: {
91
91
  enable: false,
@@ -27,7 +27,7 @@ infrastructure/
27
27
  ├── AWS-DISCOVERY-TROUBLESHOOTING.md # AWS discovery troubleshooting
28
28
  ├── DEPLOYMENT-INSTRUCTIONS.md # General deployment instructions
29
29
  ├── README-TESTING.md # Testing strategy documentation
30
- ├──
30
+ ├──
31
31
  ├── cloudformation/ # CloudFormation templates
32
32
  │ ├── monitoring-infrastructure.yaml # Enhanced monitoring (Phase 3)
33
33
  │ ├── cdn-infrastructure.yaml # CDN and UI distribution (Phase 3)
@@ -60,71 +60,79 @@ infrastructure/
60
60
  #### 1. Serverless Template Generator (`serverless-template.js`)
61
61
 
62
62
  Generates complete serverless.yml configurations with:
63
- - VPC configuration and resource discovery
64
- - KMS encryption for field-level encryption
65
- - SSM Parameter Store integration
66
- - Integration-specific functions and queues
67
- - WebSocket support for real-time features
63
+
64
+ - VPC configuration and resource discovery
65
+ - KMS encryption for field-level encryption
66
+ - SSM Parameter Store integration
67
+ - Integration-specific functions and queues
68
+ - WebSocket support for real-time features
68
69
 
69
70
  #### 2. AWS Discovery (`aws-discovery.js`)
70
71
 
71
72
  Automatically discovers existing AWS resources:
72
- - Default VPC and security groups
73
- - Private subnets for Lambda functions
74
- - Customer-managed KMS keys
75
- - Route tables for VPC endpoints
73
+
74
+ - Default VPC and security groups
75
+ - Private subnets for Lambda functions
76
+ - Customer-managed KMS keys
77
+ - Route tables for VPC endpoints
76
78
 
77
79
  #### 3. Build-Time Discovery (`build-time-discovery.js`)
78
80
 
79
81
  Integrates AWS discovery into the build process:
80
- - Pre-build hook for serverless deployments
81
- - Environment variable injection
82
- - Template variable replacement
83
- - Error handling and fallback values
82
+
83
+ - Pre-build hook for serverless deployments
84
+ - Environment variable injection
85
+ - Template variable replacement
86
+ - Error handling and fallback values
84
87
 
85
88
  ### Phase 3 Infrastructure
86
89
 
87
90
  #### 1. Enhanced Monitoring (`cloudformation/monitoring-infrastructure.yaml`)
88
91
 
89
92
  Production-ready monitoring with:
90
- - Code generation service monitoring
91
- - UI distribution monitoring
92
- - Advanced CloudWatch dashboards
93
- - Custom metrics and alarms
93
+
94
+ - Code generation service monitoring
95
+ - UI distribution monitoring
96
+ - Advanced CloudWatch dashboards
97
+ - Custom metrics and alarms
94
98
 
95
99
  #### 2. CDN Infrastructure (`cloudformation/cdn-infrastructure.yaml`)
96
100
 
97
101
  CloudFront distribution for UI packages:
98
- - S3 bucket for multi-framework UI packages
99
- - CloudFront distribution with custom domains
100
- - Lambda function for package deployment
101
- - API Gateway for package management
102
+
103
+ - S3 bucket for multi-framework UI packages
104
+ - CloudFront distribution with custom domains
105
+ - Lambda function for package deployment
106
+ - API Gateway for package management
102
107
 
103
108
  #### 3. Code Generation Infrastructure (`cloudformation/codegen-infrastructure.yaml`)
104
109
 
105
110
  Serverless code generation platform:
106
- - SQS queue for generation requests
107
- - Lambda function with AI/ML integration
108
- - DynamoDB tracking table
109
- - S3 storage for templates and generated code
110
- - ElastiCache for template caching
111
+
112
+ - SQS queue for generation requests
113
+ - Lambda function with AI/ML integration
114
+ - DynamoDB tracking table
115
+ - S3 storage for templates and generated code
116
+ - ElastiCache for template caching
111
117
 
112
118
  #### 4. Advanced Alerting (`cloudformation/alerting-infrastructure.yaml`)
113
119
 
114
120
  Multi-channel alerting system:
115
- - Multiple SNS topics for alert severity levels
116
- - Lambda function for alert processing
117
- - PagerDuty and Slack integration
118
- - Composite alarms for system health
119
- - Advanced metrics collection
121
+
122
+ - Multiple SNS topics for alert severity levels
123
+ - Lambda function for alert processing
124
+ - PagerDuty and Slack integration
125
+ - Composite alarms for system health
126
+ - Advanced metrics collection
120
127
 
121
128
  #### 5. Deployment Pipeline (`cloudformation/deployment-pipeline.yaml`)
122
129
 
123
130
  CI/CD pipeline for automated deployments:
124
- - CodePipeline with GitHub integration
125
- - CodeBuild projects for backend and UI
126
- - Multi-stage deployment workflow
127
- - Integration testing and approval gates
131
+
132
+ - CodePipeline with GitHub integration
133
+ - CodeBuild projects for backend and UI
134
+ - Multi-stage deployment workflow
135
+ - Integration testing and approval gates
128
136
 
129
137
  ## Configuration Options
130
138
 
@@ -135,7 +143,7 @@ const appDefinition = {
135
143
  // Basic configuration
136
144
  name: 'my-frigg-app',
137
145
  provider: 'aws',
138
-
146
+
139
147
  // VPC configuration
140
148
  vpc: {
141
149
  enable: true,
@@ -144,22 +152,23 @@ const appDefinition = {
144
152
  subnetIds: [...], // Optional: custom subnets
145
153
  enableVPCEndpoints: true // Optional: create VPC endpoints
146
154
  },
147
-
155
+
148
156
  // KMS encryption
149
157
  encryption: {
150
- useDefaultKMSForFieldLevelEncryption: true
158
+ fieldLevelEncryptionMethod: 'kms',
159
+ createResourceIfNoneFound: true
151
160
  },
152
-
161
+
153
162
  // SSM Parameter Store
154
163
  ssm: {
155
164
  enable: true
156
165
  },
157
-
166
+
158
167
  // WebSocket support (Phase 3)
159
168
  websockets: {
160
169
  enable: true
161
170
  },
162
-
171
+
163
172
  // Integrations
164
173
  integrations: [
165
174
  { Definition: { name: 'hubspot' } },
@@ -195,10 +204,8 @@ SERVICE_NAME=my-frigg-app
195
204
  const { composeServerlessDefinition } = require('./serverless-template');
196
205
 
197
206
  const appDefinition = {
198
- name: 'my-app',
199
- integrations: [
200
- { Definition: { name: 'hubspot' } }
201
- ]
207
+ name: 'my-app',
208
+ integrations: [{ Definition: { name: 'hubspot' } }],
202
209
  };
203
210
 
204
211
  const serverlessConfig = await composeServerlessDefinition(appDefinition);
@@ -209,13 +216,11 @@ const serverlessConfig = await composeServerlessDefinition(appDefinition);
209
216
 
210
217
  ```javascript
211
218
  const appDefinition = {
212
- name: 'secure-app',
213
- vpc: { enable: true },
214
- encryption: { useDefaultKMSForFieldLevelEncryption: true },
215
- ssm: { enable: true },
216
- integrations: [
217
- { Definition: { name: 'salesforce' } }
218
- ]
219
+ name: 'secure-app',
220
+ vpc: { enable: true },
221
+ encryption: { fieldLevelEncryptionMethod: 'kms' },
222
+ ssm: { enable: true },
223
+ integrations: [{ Definition: { name: 'salesforce' } }],
219
224
  };
220
225
 
221
226
  const serverlessConfig = await composeServerlessDefinition(appDefinition);
@@ -225,12 +230,10 @@ const serverlessConfig = await composeServerlessDefinition(appDefinition);
225
230
 
226
231
  ```javascript
227
232
  const appDefinition = {
228
- name: 'realtime-app',
229
- websockets: { enable: true },
230
- vpc: { enable: true },
231
- integrations: [
232
- { Definition: { name: 'slack' } }
233
- ]
233
+ name: 'realtime-app',
234
+ websockets: { enable: true },
235
+ vpc: { enable: true },
236
+ integrations: [{ Definition: { name: 'slack' } }],
234
237
  };
235
238
 
236
239
  const serverlessConfig = await composeServerlessDefinition(appDefinition);
@@ -259,19 +262,21 @@ npm test -- --watch
259
262
  ### Test Categories
260
263
 
261
264
  1. **Unit Tests**: Test individual components
262
- - AWS discovery utilities
263
- - Serverless template generation
264
- - IAM policy generation
265
+
266
+ - AWS discovery utilities
267
+ - Serverless template generation
268
+ - IAM policy generation
265
269
 
266
270
  2. **Integration Tests**: Test end-to-end workflows
267
- - Complete discovery and template generation
268
- - Plugin integration
269
- - Phase 3 infrastructure validation
271
+
272
+ - Complete discovery and template generation
273
+ - Plugin integration
274
+ - Phase 3 infrastructure validation
270
275
 
271
276
  3. **Performance Tests**: Validate infrastructure limits
272
- - CloudFormation template sizes
273
- - Resource count limits
274
- - Cross-stack dependencies
277
+ - CloudFormation template sizes
278
+ - Resource count limits
279
+ - Cross-stack dependencies
275
280
 
276
281
  ### Mock Data
277
282
 
@@ -279,11 +284,12 @@ Tests use mock AWS resources to avoid real AWS API calls:
279
284
 
280
285
  ```javascript
281
286
  const mockAWSResources = {
282
- defaultVpcId: 'vpc-12345678',
283
- defaultSecurityGroupId: 'sg-12345678',
284
- privateSubnetId1: 'subnet-private-1',
285
- privateSubnetId2: 'subnet-private-2',
286
- defaultKmsKeyId: 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012'
287
+ defaultVpcId: 'vpc-12345678',
288
+ defaultSecurityGroupId: 'sg-12345678',
289
+ privateSubnetId1: 'subnet-private-1',
290
+ privateSubnetId2: 'subnet-private-2',
291
+ defaultKmsKeyId:
292
+ 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012',
287
293
  };
288
294
  ```
289
295
 
@@ -293,18 +299,18 @@ const mockAWSResources = {
293
299
 
294
300
  The infrastructure requires specific IAM permissions for AWS resource discovery and deployment:
295
301
 
296
- - **EC2**: Describe VPCs, subnets, security groups, route tables
297
- - **KMS**: List keys, describe keys
298
- - **STS**: Get caller identity
299
- - **CloudFormation**: Full access for stack operations
300
- - **Lambda**: Function management
301
- - **API Gateway**: API management
302
- - **S3**: Bucket and object operations (including tagging)
303
- - **DynamoDB**: Table operations
304
- - **SQS**: Queue operations
305
- - **SNS**: Topic operations
306
- - **CloudWatch**: Metrics and alarms
307
- - **IAM**: Role and policy management
302
+ - **EC2**: Describe VPCs, subnets, security groups, route tables
303
+ - **KMS**: List keys, describe keys
304
+ - **STS**: Get caller identity
305
+ - **CloudFormation**: Full access for stack operations
306
+ - **Lambda**: Function management
307
+ - **API Gateway**: API management
308
+ - **S3**: Bucket and object operations (including tagging)
309
+ - **DynamoDB**: Table operations
310
+ - **SQS**: Queue operations
311
+ - **SNS**: Topic operations
312
+ - **CloudWatch**: Metrics and alarms
313
+ - **IAM**: Role and policy management
308
314
 
309
315
  ### Best Practices
310
316
 
@@ -348,6 +354,8 @@ serverless print
348
354
  aws cloudformation validate-template --template-body file://template.json
349
355
  ```
350
356
 
357
+ - **Connectivity to external services (e.g., databases):** If your Lambda functions in a VPC cannot connect to external services, ensure that the `FriggLambdaSecurityGroup` has the correct **egress** rules to allow outbound traffic on the required ports (e.g., port 27017 for MongoDB).
358
+
351
359
  #### Infrastructure Test Failures
352
360
 
353
361
  ```bash
@@ -364,19 +372,22 @@ npm run test:debug
364
372
  ### Performance Optimization
365
373
 
366
374
  #### Lambda Cold Starts
367
- - Use provisioned concurrency for critical functions
368
- - Optimize function size and dependencies
369
- - Monitor cold start metrics
375
+
376
+ - Use provisioned concurrency for critical functions
377
+ - Optimize function size and dependencies
378
+ - Monitor cold start metrics
370
379
 
371
380
  #### VPC Performance
372
- - Use VPC endpoints to reduce NAT Gateway costs
373
- - Monitor ENI creation/deletion times
374
- - Consider Lambda@Edge for global distribution
381
+
382
+ - Use VPC endpoints to reduce NAT Gateway costs
383
+ - Monitor ENI creation/deletion times
384
+ - Consider Lambda@Edge for global distribution
375
385
 
376
386
  #### Cost Optimization
377
- - Use S3 Intelligent Tiering
378
- - Configure CloudWatch log retention
379
- - Monitor and alert on unexpected usage
387
+
388
+ - Use S3 Intelligent Tiering
389
+ - Configure CloudWatch log retention
390
+ - Monitor and alert on unexpected usage
380
391
 
381
392
  ## Contributing
382
393
 
@@ -405,17 +416,17 @@ npm run test:debug
405
416
 
406
417
  ## Support
407
418
 
408
- - **Documentation**: See `PHASE3-DEPLOYMENT-GUIDE.md` for detailed deployment instructions
409
- - **Testing**: See `README-TESTING.md` for testing strategy
410
- - **Troubleshooting**: See `AWS-DISCOVERY-TROUBLESHOOTING.md` for common issues
411
- - **Issues**: Create GitHub issues for bugs and feature requests
412
- - **Discussions**: Use GitHub Discussions for questions and ideas
419
+ - **Documentation**: See `PHASE3-DEPLOYMENT-GUIDE.md` for detailed deployment instructions
420
+ - **Testing**: See `README-TESTING.md` for testing strategy
421
+ - **Troubleshooting**: See `AWS-DISCOVERY-TROUBLESHOOTING.md` for common issues
422
+ - **Issues**: Create GitHub issues for bugs and feature requests
423
+ - **Discussions**: Use GitHub Discussions for questions and ideas
413
424
 
414
425
  ## Related Documentation
415
426
 
416
- - [Phase 3 Deployment Guide](./PHASE3-DEPLOYMENT-GUIDE.md)
417
- - [Testing Strategy](./README-TESTING.md)
418
- - [AWS Discovery Troubleshooting](./AWS-DISCOVERY-TROUBLESHOOTING.md)
419
- - [IAM Policy Templates](./IAM-POLICY-TEMPLATES.md)
420
- - [VPC Configuration](./VPC-CONFIGURATION.md)
421
- - [WebSocket Configuration](./WEBSOCKET-CONFIGURATION.md)
427
+ - [Phase 3 Deployment Guide](./PHASE3-DEPLOYMENT-GUIDE.md)
428
+ - [Testing Strategy](./README-TESTING.md)
429
+ - [AWS Discovery Troubleshooting](./AWS-DISCOVERY-TROUBLESHOOTING.md)
430
+ - [IAM Policy Templates](./IAM-POLICY-TEMPLATES.md)
431
+ - [VPC Configuration](./VPC-CONFIGURATION.md)
432
+ - [WebSocket Configuration](./WEBSOCKET-CONFIGURATION.md)
@@ -151,7 +151,7 @@ const mockAppDefinitions = {
151
151
 
152
152
  kmsOnly: {
153
153
  name: 'kms-test-app',
154
- encryption: { useDefaultKMSForFieldLevelEncryption: true },
154
+ encryption: { fieldLevelEncryptionMethod: 'kms' },
155
155
  integrations: []
156
156
  },
157
157
 
@@ -164,7 +164,7 @@ const mockAppDefinitions = {
164
164
  allFeatures: {
165
165
  name: 'full-feature-app',
166
166
  vpc: { enable: true },
167
- encryption: { useDefaultKMSForFieldLevelEncryption: true },
167
+ encryption: { fieldLevelEncryptionMethod: 'kms' },
168
168
  ssm: { enable: true },
169
169
  integrations: [{
170
170
  Definition: {
@@ -281,7 +281,7 @@ const mockEnvironmentVariables = {
281
281
  AWS_DISCOVERY_SUBNET_ID_1: mockSubnets[0].SubnetId,
282
282
  AWS_DISCOVERY_SUBNET_ID_2: mockSubnets[1].SubnetId,
283
283
  AWS_DISCOVERY_ROUTE_TABLE_ID: mockRouteTables[0].RouteTableId,
284
- AWS_DISCOVERY_KMS_KEY_ID: mockKmsKeyMetadata.Arn
284
+ AWS_DISCOVERY_KMS_KEY_ID:mockKmsKeyMetadata.Arn
285
285
  };
286
286
 
287
287
  // Fallback environment variables for error scenarios
@@ -291,7 +291,7 @@ const mockFallbackEnvironmentVariables = {
291
291
  AWS_DISCOVERY_SUBNET_ID_1: 'subnet-fallback-1',
292
292
  AWS_DISCOVERY_SUBNET_ID_2: 'subnet-fallback-2',
293
293
  AWS_DISCOVERY_ROUTE_TABLE_ID: 'rtb-fallback',
294
- AWS_DISCOVERY_KMS_KEY_ID: 'arn:aws:kms:*:*:key/*'
294
+ AWS_DISCOVERY_KMS_KEY_ID:'arn:aws:kms:*:*:key/*'
295
295
  };
296
296
 
297
297
  // Mock AWS SDK responses
@@ -115,7 +115,7 @@ function createMockAppDefinition(features = {}, integrations = []) {
115
115
  }
116
116
 
117
117
  if (features.kms) {
118
- appDefinition.encryption = { useDefaultKMSForFieldLevelEncryption: true };
118
+ appDefinition.encryption = { fieldLevelEncryptionMethod: 'kms' };
119
119
  }
120
120
 
121
121
  if (features.ssm) {
@@ -453,18 +453,16 @@ class AWSDiscovery {
453
453
 
454
454
  /**
455
455
  * Find the default KMS key for the account
456
- * @returns {Promise<string>} KMS key ARN or wildcard pattern as fallback
456
+ * @returns {Promise<string|null>} KMS key ARN or null if no key found
457
457
  */
458
458
  async findDefaultKmsKey() {
459
459
  try {
460
- // First try to find a key with alias/aws/lambda
461
460
  const command = new ListKeysCommand({});
462
461
  const response = await this.kmsClient.send(command);
463
462
 
464
463
  if (!response.Keys || response.Keys.length === 0) {
465
- // Return AWS managed key ARN pattern as fallback
466
- const accountId = await this.getAccountId();
467
- return `arn:aws:kms:${this.region}:${accountId}:key/*`;
464
+ console.log('No KMS keys found in account');
465
+ return null;
468
466
  }
469
467
 
470
468
  // Look for customer managed keys first
@@ -476,21 +474,21 @@ class AWSDiscovery {
476
474
  if (keyDetails.KeyMetadata &&
477
475
  keyDetails.KeyMetadata.KeyManager === 'CUSTOMER' &&
478
476
  keyDetails.KeyMetadata.KeyState === 'Enabled') {
477
+ console.log(`Found customer managed KMS key: ${keyDetails.KeyMetadata.Arn}`);
479
478
  return keyDetails.KeyMetadata.Arn;
480
479
  }
481
480
  } catch (error) {
482
481
  // Continue to next key if we can't describe this one
482
+ console.warn(`Could not describe key ${key.KeyId}:`, error.message);
483
483
  continue;
484
484
  }
485
485
  }
486
486
 
487
- // Fallback to wildcard pattern for AWS managed keys
488
- const accountId = await this.getAccountId();
489
- return `arn:aws:kms:${this.region}:${accountId}:key/*`;
487
+ console.log('No customer managed KMS keys found');
488
+ return null;
490
489
  } catch (error) {
491
490
  console.error('Error finding default KMS key:', error);
492
- // Return wildcard pattern as ultimate fallback
493
- return '*';
491
+ return null;
494
492
  }
495
493
  }
496
494
 
@@ -503,7 +501,7 @@ class AWSDiscovery {
503
501
  * @returns {string} return.privateSubnetId2 - Second private subnet ID
504
502
  * @returns {string} return.publicSubnetId - Public subnet ID for NAT Gateway
505
503
  * @returns {string} return.privateRouteTableId - Private route table ID
506
- * @returns {string} return.defaultKmsKeyId - Default KMS key ARN
504
+ * @returns {string|null} return.defaultKmsKeyId - Default KMS key ARN or null if not found
507
505
  * @throws {Error} If resource discovery fails
508
506
  */
509
507
  async discoverResources() {
@@ -526,7 +524,11 @@ class AWSDiscovery {
526
524
  console.log(`Found route table: ${routeTable.RouteTableId}`);
527
525
 
528
526
  const kmsKeyArn = await this.findDefaultKmsKey();
529
- console.log(`Found KMS key: ${kmsKeyArn}`);
527
+ if (kmsKeyArn) {
528
+ console.log(`Found KMS key: ${kmsKeyArn}`);
529
+ } else {
530
+ console.log('No KMS key found');
531
+ }
530
532
 
531
533
  // Try to find existing NAT Gateway
532
534
  const existingNatGateway = await this.findExistingNatGateway(vpc.VpcId);
@@ -137,8 +137,8 @@ class BuildTimeDiscovery {
137
137
  console.log('Running pre-build AWS discovery hook...');
138
138
 
139
139
  // Only run discovery if VPC, KMS, or SSM features are enabled
140
- const needsDiscovery = appDefinition.vpc?.enable ||
141
- appDefinition.encryption?.useDefaultKMSForFieldLevelEncryption ||
140
+ const needsDiscovery = appDefinition.vpc?.enable ||
141
+ appDefinition.encryption?.fieldLevelEncryptionMethod === 'kms' ||
142
142
  appDefinition.ssm?.enable;
143
143
 
144
144
  if (!needsDiscovery) {
@@ -159,7 +159,7 @@ class BuildTimeDiscovery {
159
159
  AWS_DISCOVERY_SUBNET_ID_2: resources.privateSubnetId2,
160
160
  AWS_DISCOVERY_PUBLIC_SUBNET_ID: resources.publicSubnetId,
161
161
  AWS_DISCOVERY_ROUTE_TABLE_ID: resources.privateRouteTableId,
162
- AWS_DISCOVERY_KMS_KEY_ID: resources.defaultKmsKeyId
162
+ AWS_DISCOVERY_KMS_KEY_ID: resources.defaultKmsKeyId // Keep consistent naming convention (even though it's an ARN)
163
163
  };
164
164
 
165
165
  // Set environment variables for serverless to use
@@ -250,7 +250,7 @@ describe('BuildTimeDiscovery', () => {
250
250
 
251
251
  it('should run discovery when KMS is enabled', async () => {
252
252
  const appDefinition = {
253
- encryption: { useDefaultKMSForFieldLevelEncryption: true },
253
+ encryption: { fieldLevelEncryptionMethod: 'kms' },
254
254
  integrations: []
255
255
  };
256
256
 
@@ -35,7 +35,7 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
35
35
  vpc: appDefinition.vpc?.enable === true,
36
36
  kms:
37
37
  appDefinition.encryption
38
- ?.useDefaultKMSForFieldLevelEncryption === true,
38
+ ?.fieldLevelEncryptionMethod === 'kms',
39
39
  ssm: appDefinition.ssm?.enable === true,
40
40
  websockets: appDefinition.websockets?.enable === true,
41
41
  };
@@ -605,6 +605,19 @@ function generateIAMCloudFormation(appDefinition, options = {}) {
605
605
  },
606
606
  },
607
607
  },
608
+ {
609
+ Sid: 'FriggKMSManagement',
610
+ Effect: 'Allow',
611
+ Action: [
612
+ 'kms:CreateKey',
613
+ 'kms:PutKeyPolicy',
614
+ 'kms:EnableKeyRotation',
615
+ 'kms:TagResource',
616
+ 'kms:UntagResource',
617
+ 'kms:ListResourceTags',
618
+ ],
619
+ Resource: '*',
620
+ },
608
621
  ],
609
622
  },
610
623
  },
@@ -724,8 +737,7 @@ function getFeatureSummary(appDefinition) {
724
737
  core: true, // Always enabled
725
738
  vpc: appDefinition.vpc?.enable === true,
726
739
  kms:
727
- appDefinition.encryption?.useDefaultKMSForFieldLevelEncryption ===
728
- true,
740
+ appDefinition.encryption?.fieldLevelEncryptionMethod === 'kms',
729
741
  ssm: appDefinition.ssm?.enable === true,
730
742
  websockets: appDefinition.websockets?.enable === true,
731
743
  };
@@ -7,7 +7,7 @@ describe('IAM Generator', () => {
7
7
  name: 'test-app',
8
8
  integrations: ['Integration1', 'Integration2'],
9
9
  vpc: { enable: true },
10
- encryption: { useDefaultKMSForFieldLevelEncryption: true },
10
+ encryption: { fieldLevelEncryptionMethod: 'kms' },
11
11
  ssm: { enable: true },
12
12
  websockets: { enable: true }
13
13
  };
@@ -46,7 +46,7 @@ describe('IAM Generator', () => {
46
46
  name: 'test-app',
47
47
  integrations: [],
48
48
  vpc: { enable: false },
49
- encryption: { useDefaultKMSForFieldLevelEncryption: false },
49
+ encryption: { fieldLevelEncryptionMethod: 'aes' },
50
50
  ssm: { enable: false },
51
51
  websockets: { enable: false }
52
52
  };
@@ -77,7 +77,7 @@ describe('IAM Generator', () => {
77
77
  const appDefinition = {
78
78
  name: 'test-app',
79
79
  integrations: [],
80
- encryption: { useDefaultKMSForFieldLevelEncryption: true }
80
+ encryption: { fieldLevelEncryptionMethod: 'kms' }
81
81
  };
82
82
 
83
83
  const yaml = generateIAMCloudFormation(appDefinition);
@@ -106,7 +106,7 @@ describe('IAM Generator', () => {
106
106
  name: 'test-app',
107
107
  integrations: [],
108
108
  vpc: { enable: true },
109
- encryption: { useDefaultKMSForFieldLevelEncryption: false },
109
+ encryption: { fieldLevelEncryptionMethod: 'aes' },
110
110
  ssm: { enable: true }
111
111
  };
112
112