@friggframework/devtools 2.0.0--canary.398.4f043c8.0 → 2.0.0--canary.397.5f65dbd.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.
Files changed (31) hide show
  1. package/frigg-cli/build-command/index.js +2 -4
  2. package/frigg-cli/deploy-command/index.js +2 -5
  3. package/frigg-cli/index.js +1 -11
  4. package/infrastructure/create-frigg-infrastructure.js +2 -10
  5. package/infrastructure/serverless-template.js +48 -659
  6. package/package.json +5 -9
  7. package/test/index.js +2 -4
  8. package/test/mock-integration.js +4 -14
  9. package/frigg-cli/generate-iam-command.js +0 -115
  10. package/infrastructure/AWS-DISCOVERY-TROUBLESHOOTING.md +0 -245
  11. package/infrastructure/AWS-IAM-CREDENTIAL-NEEDS.md +0 -594
  12. package/infrastructure/DEPLOYMENT-INSTRUCTIONS.md +0 -268
  13. package/infrastructure/GENERATE-IAM-DOCS.md +0 -253
  14. package/infrastructure/IAM-POLICY-TEMPLATES.md +0 -175
  15. package/infrastructure/README-TESTING.md +0 -332
  16. package/infrastructure/WEBSOCKET-CONFIGURATION.md +0 -105
  17. package/infrastructure/__tests__/fixtures/mock-aws-resources.js +0 -391
  18. package/infrastructure/__tests__/helpers/test-utils.js +0 -277
  19. package/infrastructure/aws-discovery.js +0 -568
  20. package/infrastructure/aws-discovery.test.js +0 -373
  21. package/infrastructure/build-time-discovery.js +0 -206
  22. package/infrastructure/build-time-discovery.test.js +0 -375
  23. package/infrastructure/frigg-deployment-iam-stack.yaml +0 -377
  24. package/infrastructure/iam-generator.js +0 -696
  25. package/infrastructure/iam-generator.test.js +0 -169
  26. package/infrastructure/iam-policy-basic.json +0 -210
  27. package/infrastructure/iam-policy-full.json +0 -280
  28. package/infrastructure/integration.test.js +0 -383
  29. package/infrastructure/run-discovery.js +0 -110
  30. package/infrastructure/serverless-template.test.js +0 -541
  31. package/test/auther-definition-tester.js +0 -125
@@ -1,696 +0,0 @@
1
- const fs = require('fs-extra');
2
- const path = require('path');
3
-
4
- /**
5
- * Generate IAM CloudFormation template based on AppDefinition
6
- * @param {Object} appDefinition - Application definition object
7
- * @param {Object} options - Generation options
8
- * @param {string} [options.deploymentUserName='frigg-deployment-user'] - IAM user name
9
- * @param {string} [options.stackName='frigg-deployment-iam'] - CloudFormation stack name
10
- * @param {string} [options.mode='auto'] - Policy mode: 'basic', 'full', or 'auto' (auto-detect from appDefinition)
11
- * @returns {string} CloudFormation YAML template
12
- */
13
- function generateIAMCloudFormation(appDefinition, options = {}) {
14
- const {
15
- deploymentUserName = 'frigg-deployment-user',
16
- stackName = 'frigg-deployment-iam',
17
- mode = 'auto'
18
- } = options;
19
-
20
- // Determine which features are enabled based on mode
21
- let features;
22
- if (mode === 'basic') {
23
- features = {
24
- vpc: false,
25
- kms: false,
26
- ssm: false,
27
- websockets: appDefinition.websockets?.enable === true
28
- };
29
- } else if (mode === 'full') {
30
- features = {
31
- vpc: true,
32
- kms: true,
33
- ssm: true,
34
- websockets: appDefinition.websockets?.enable === true
35
- };
36
- } else { // mode === 'auto'
37
- features = {
38
- vpc: appDefinition.vpc?.enable === true,
39
- kms: appDefinition.encryption?.useDefaultKMSForFieldLevelEncryption === true,
40
- ssm: appDefinition.ssm?.enable === true,
41
- websockets: appDefinition.websockets?.enable === true
42
- };
43
- }
44
-
45
- // Build the CloudFormation template
46
- const template = {
47
- AWSTemplateFormatVersion: '2010-09-09',
48
- Description: `IAM roles and policies for ${appDefinition.name || 'Frigg'} application deployment pipeline`,
49
-
50
- Parameters: {
51
- DeploymentUserName: {
52
- Type: 'String',
53
- Default: deploymentUserName,
54
- Description: 'Name for the IAM user that will deploy Frigg applications'
55
- },
56
- EnableVPCSupport: {
57
- Type: 'String',
58
- Default: features.vpc ? 'true' : 'false',
59
- AllowedValues: ['true', 'false'],
60
- Description: 'Enable VPC-related permissions for Frigg applications'
61
- },
62
- EnableKMSSupport: {
63
- Type: 'String',
64
- Default: features.kms ? 'true' : 'false',
65
- AllowedValues: ['true', 'false'],
66
- Description: 'Enable KMS encryption permissions for Frigg applications'
67
- },
68
- EnableSSMSupport: {
69
- Type: 'String',
70
- Default: features.ssm ? 'true' : 'false',
71
- AllowedValues: ['true', 'false'],
72
- Description: 'Enable SSM Parameter Store permissions for Frigg applications'
73
- }
74
- },
75
-
76
- Conditions: {
77
- CreateVPCPermissions: { 'Fn::Equals': [{ Ref: 'EnableVPCSupport' }, 'true'] },
78
- CreateKMSPermissions: { 'Fn::Equals': [{ Ref: 'EnableKMSSupport' }, 'true'] },
79
- CreateSSMPermissions: { 'Fn::Equals': [{ Ref: 'EnableSSMSupport' }, 'true'] }
80
- },
81
-
82
- Resources: {}
83
- };
84
-
85
- // Add IAM User
86
- template.Resources.FriggDeploymentUser = {
87
- Type: 'AWS::IAM::User',
88
- Properties: {
89
- UserName: { Ref: 'DeploymentUserName' },
90
- ManagedPolicyArns: [
91
- { Ref: 'FriggDiscoveryPolicy' },
92
- { Ref: 'FriggCoreDeploymentPolicy' }
93
- ]
94
- }
95
- };
96
-
97
- // Conditionally add feature-specific policies
98
- if (features.vpc) {
99
- template.Resources.FriggDeploymentUser.Properties.ManagedPolicyArns.push({
100
- 'Fn::If': ['CreateVPCPermissions', { Ref: 'FriggVPCPolicy' }, { Ref: 'AWS::NoValue' }]
101
- });
102
- }
103
- if (features.kms) {
104
- template.Resources.FriggDeploymentUser.Properties.ManagedPolicyArns.push({
105
- 'Fn::If': ['CreateKMSPermissions', { Ref: 'FriggKMSPolicy' }, { Ref: 'AWS::NoValue' }]
106
- });
107
- }
108
- if (features.ssm) {
109
- template.Resources.FriggDeploymentUser.Properties.ManagedPolicyArns.push({
110
- 'Fn::If': ['CreateSSMPermissions', { Ref: 'FriggSSMPolicy' }, { Ref: 'AWS::NoValue' }]
111
- });
112
- }
113
-
114
- // Add Access Key
115
- template.Resources.FriggDeploymentAccessKey = {
116
- Type: 'AWS::IAM::AccessKey',
117
- Properties: {
118
- UserName: { Ref: 'FriggDeploymentUser' }
119
- }
120
- };
121
-
122
- // Add Discovery Policy (always needed)
123
- template.Resources.FriggDiscoveryPolicy = {
124
- Type: 'AWS::IAM::ManagedPolicy',
125
- Properties: {
126
- ManagedPolicyName: 'FriggDiscoveryPolicy',
127
- Description: 'Permissions for AWS resource discovery during Frigg build process',
128
- PolicyDocument: {
129
- Version: '2012-10-17',
130
- Statement: [
131
- {
132
- Sid: 'AWSDiscoveryPermissions',
133
- Effect: 'Allow',
134
- Action: [
135
- 'sts:GetCallerIdentity',
136
- 'ec2:DescribeVpcs',
137
- 'ec2:DescribeSubnets',
138
- 'ec2:DescribeSecurityGroups',
139
- 'ec2:DescribeRouteTables',
140
- 'kms:ListKeys',
141
- 'kms:DescribeKey'
142
- ],
143
- Resource: '*'
144
- }
145
- ]
146
- }
147
- }
148
- };
149
-
150
- // Add Core Deployment Policy (always needed)
151
- const coreActions = [
152
- // CloudFormation permissions
153
- 'cloudformation:CreateStack',
154
- 'cloudformation:UpdateStack',
155
- 'cloudformation:DeleteStack',
156
- 'cloudformation:DescribeStacks',
157
- 'cloudformation:DescribeStackEvents',
158
- 'cloudformation:DescribeStackResources',
159
- 'cloudformation:DescribeStackResource',
160
- 'cloudformation:ListStackResources',
161
- 'cloudformation:GetTemplate',
162
- 'cloudformation:DescribeChangeSet',
163
- 'cloudformation:CreateChangeSet',
164
- 'cloudformation:DeleteChangeSet',
165
- 'cloudformation:ExecuteChangeSet',
166
- 'cloudformation:ValidateTemplate',
167
-
168
- // Lambda permissions
169
- 'lambda:CreateFunction',
170
- 'lambda:UpdateFunctionCode',
171
- 'lambda:UpdateFunctionConfiguration',
172
- 'lambda:DeleteFunction',
173
- 'lambda:GetFunction',
174
- 'lambda:ListFunctions',
175
- 'lambda:PublishVersion',
176
- 'lambda:CreateAlias',
177
- 'lambda:UpdateAlias',
178
- 'lambda:DeleteAlias',
179
- 'lambda:GetAlias',
180
- 'lambda:AddPermission',
181
- 'lambda:RemovePermission',
182
- 'lambda:GetPolicy',
183
- 'lambda:PutProvisionedConcurrencyConfig',
184
- 'lambda:DeleteProvisionedConcurrencyConfig',
185
- 'lambda:PutConcurrency',
186
- 'lambda:DeleteConcurrency',
187
- 'lambda:TagResource',
188
- 'lambda:UntagResource',
189
- 'lambda:ListVersionsByFunction',
190
-
191
- // IAM permissions
192
- 'iam:CreateRole',
193
- 'iam:DeleteRole',
194
- 'iam:GetRole',
195
- 'iam:PassRole',
196
- 'iam:PutRolePolicy',
197
- 'iam:DeleteRolePolicy',
198
- 'iam:GetRolePolicy',
199
- 'iam:AttachRolePolicy',
200
- 'iam:DetachRolePolicy',
201
- 'iam:TagRole',
202
- 'iam:UntagRole',
203
- 'iam:ListPolicyVersions',
204
-
205
- // S3 permissions
206
- 's3:CreateBucket',
207
- 's3:PutObject',
208
- 's3:GetObject',
209
- 's3:DeleteObject',
210
- 's3:PutBucketPolicy',
211
- 's3:PutBucketVersioning',
212
- 's3:PutBucketPublicAccessBlock',
213
- 's3:GetBucketLocation',
214
- 's3:ListBucket',
215
-
216
- // SQS permissions
217
- 'sqs:CreateQueue',
218
- 'sqs:DeleteQueue',
219
- 'sqs:GetQueueAttributes',
220
- 'sqs:SetQueueAttributes',
221
- 'sqs:GetQueueUrl',
222
- 'sqs:TagQueue',
223
- 'sqs:UntagQueue',
224
-
225
- // SNS permissions
226
- 'sns:CreateTopic',
227
- 'sns:DeleteTopic',
228
- 'sns:GetTopicAttributes',
229
- 'sns:SetTopicAttributes',
230
- 'sns:Subscribe',
231
- 'sns:Unsubscribe',
232
- 'sns:ListSubscriptionsByTopic',
233
- 'sns:TagResource',
234
- 'sns:UntagResource',
235
-
236
- // CloudWatch and Logs permissions
237
- 'cloudwatch:PutMetricAlarm',
238
- 'cloudwatch:DeleteAlarms',
239
- 'cloudwatch:DescribeAlarms',
240
- 'logs:CreateLogGroup',
241
- 'logs:CreateLogStream',
242
- 'logs:DeleteLogGroup',
243
- 'logs:DescribeLogGroups',
244
- 'logs:DescribeLogStreams',
245
- 'logs:FilterLogEvents',
246
- 'logs:PutLogEvents',
247
- 'logs:PutRetentionPolicy',
248
-
249
- // API Gateway permissions
250
- 'apigateway:POST',
251
- 'apigateway:PUT',
252
- 'apigateway:DELETE',
253
- 'apigateway:GET',
254
- 'apigateway:PATCH'
255
- ];
256
-
257
- const coreStatements = [
258
- {
259
- Sid: 'CloudFormationFriggStacks',
260
- Effect: 'Allow',
261
- Action: [
262
- 'cloudformation:CreateStack',
263
- 'cloudformation:UpdateStack',
264
- 'cloudformation:DeleteStack',
265
- 'cloudformation:DescribeStacks',
266
- 'cloudformation:DescribeStackEvents',
267
- 'cloudformation:DescribeStackResources',
268
- 'cloudformation:DescribeStackResource',
269
- 'cloudformation:ListStackResources',
270
- 'cloudformation:GetTemplate',
271
- 'cloudformation:DescribeChangeSet',
272
- 'cloudformation:CreateChangeSet',
273
- 'cloudformation:DeleteChangeSet',
274
- 'cloudformation:ExecuteChangeSet'
275
- ],
276
- Resource: [
277
- { 'Fn::Sub': 'arn:aws:cloudformation:*:${AWS::AccountId}:stack/*frigg*/*' }
278
- ]
279
- },
280
- {
281
- Sid: 'CloudFormationValidateTemplate',
282
- Effect: 'Allow',
283
- Action: ['cloudformation:ValidateTemplate'],
284
- Resource: '*'
285
- },
286
- {
287
- Sid: 'S3DeploymentBucket',
288
- Effect: 'Allow',
289
- Action: [
290
- 's3:CreateBucket',
291
- 's3:PutObject',
292
- 's3:GetObject',
293
- 's3:DeleteObject',
294
- 's3:PutBucketPolicy',
295
- 's3:PutBucketVersioning',
296
- 's3:PutBucketPublicAccessBlock',
297
- 's3:GetBucketLocation',
298
- 's3:ListBucket'
299
- ],
300
- Resource: [
301
- 'arn:aws:s3:::*serverless*',
302
- 'arn:aws:s3:::*serverless*/*'
303
- ]
304
- },
305
- {
306
- Sid: 'LambdaFriggFunctions',
307
- Effect: 'Allow',
308
- Action: [
309
- 'lambda:CreateFunction',
310
- 'lambda:UpdateFunctionCode',
311
- 'lambda:UpdateFunctionConfiguration',
312
- 'lambda:DeleteFunction',
313
- 'lambda:GetFunction',
314
- 'lambda:ListFunctions',
315
- 'lambda:PublishVersion',
316
- 'lambda:CreateAlias',
317
- 'lambda:UpdateAlias',
318
- 'lambda:DeleteAlias',
319
- 'lambda:GetAlias',
320
- 'lambda:AddPermission',
321
- 'lambda:RemovePermission',
322
- 'lambda:GetPolicy',
323
- 'lambda:PutProvisionedConcurrencyConfig',
324
- 'lambda:DeleteProvisionedConcurrencyConfig',
325
- 'lambda:PutConcurrency',
326
- 'lambda:DeleteConcurrency',
327
- 'lambda:TagResource',
328
- 'lambda:UntagResource',
329
- 'lambda:ListVersionsByFunction'
330
- ],
331
- Resource: [
332
- { 'Fn::Sub': 'arn:aws:lambda:*:${AWS::AccountId}:function:*frigg*' }
333
- ]
334
- },
335
- {
336
- Sid: 'IAMRolesForFriggLambda',
337
- Effect: 'Allow',
338
- Action: [
339
- 'iam:CreateRole',
340
- 'iam:DeleteRole',
341
- 'iam:GetRole',
342
- 'iam:PassRole',
343
- 'iam:PutRolePolicy',
344
- 'iam:DeleteRolePolicy',
345
- 'iam:GetRolePolicy',
346
- 'iam:AttachRolePolicy',
347
- 'iam:DetachRolePolicy',
348
- 'iam:TagRole',
349
- 'iam:UntagRole'
350
- ],
351
- Resource: [
352
- { 'Fn::Sub': 'arn:aws:iam::${AWS::AccountId}:role/*frigg*' },
353
- { 'Fn::Sub': 'arn:aws:iam::${AWS::AccountId}:role/*frigg*LambdaRole*' }
354
- ]
355
- },
356
- {
357
- Sid: 'IAMPolicyVersionPermissions',
358
- Effect: 'Allow',
359
- Action: ['iam:ListPolicyVersions'],
360
- Resource: [{ 'Fn::Sub': 'arn:aws:iam::${AWS::AccountId}:policy/*' }]
361
- },
362
- {
363
- Sid: 'FriggMessagingServices',
364
- Effect: 'Allow',
365
- Action: [
366
- 'sqs:CreateQueue',
367
- 'sqs:DeleteQueue',
368
- 'sqs:GetQueueAttributes',
369
- 'sqs:SetQueueAttributes',
370
- 'sqs:GetQueueUrl',
371
- 'sqs:TagQueue',
372
- 'sqs:UntagQueue'
373
- ],
374
- Resource: [
375
- { 'Fn::Sub': 'arn:aws:sqs:*:${AWS::AccountId}:*frigg*' },
376
- { 'Fn::Sub': 'arn:aws:sqs:*:${AWS::AccountId}:internal-error-queue-*' }
377
- ]
378
- },
379
- {
380
- Sid: 'FriggSNSTopics',
381
- Effect: 'Allow',
382
- Action: [
383
- 'sns:CreateTopic',
384
- 'sns:DeleteTopic',
385
- 'sns:GetTopicAttributes',
386
- 'sns:SetTopicAttributes',
387
- 'sns:Subscribe',
388
- 'sns:Unsubscribe',
389
- 'sns:ListSubscriptionsByTopic',
390
- 'sns:TagResource',
391
- 'sns:UntagResource'
392
- ],
393
- Resource: [
394
- { 'Fn::Sub': 'arn:aws:sns:*:${AWS::AccountId}:*frigg*' }
395
- ]
396
- },
397
- {
398
- Sid: 'FriggMonitoringAndLogs',
399
- Effect: 'Allow',
400
- Action: [
401
- 'cloudwatch:PutMetricAlarm',
402
- 'cloudwatch:DeleteAlarms',
403
- 'cloudwatch:DescribeAlarms',
404
- 'logs:CreateLogGroup',
405
- 'logs:CreateLogStream',
406
- 'logs:DeleteLogGroup',
407
- 'logs:DescribeLogGroups',
408
- 'logs:DescribeLogStreams',
409
- 'logs:FilterLogEvents',
410
- 'logs:PutLogEvents',
411
- 'logs:PutRetentionPolicy'
412
- ],
413
- Resource: [
414
- { 'Fn::Sub': 'arn:aws:logs:*:${AWS::AccountId}:log-group:/aws/lambda/*frigg*' },
415
- { 'Fn::Sub': 'arn:aws:logs:*:${AWS::AccountId}:log-group:/aws/lambda/*frigg*:*' },
416
- { 'Fn::Sub': 'arn:aws:cloudwatch:*:${AWS::AccountId}:alarm:*frigg*' }
417
- ]
418
- },
419
- {
420
- Sid: 'FriggAPIGateway',
421
- Effect: 'Allow',
422
- Action: [
423
- 'apigateway:POST',
424
- 'apigateway:PUT',
425
- 'apigateway:DELETE',
426
- 'apigateway:GET',
427
- 'apigateway:PATCH'
428
- ],
429
- Resource: [
430
- 'arn:aws:apigateway:*::/restapis',
431
- 'arn:aws:apigateway:*::/restapis/*',
432
- 'arn:aws:apigateway:*::/domainnames',
433
- 'arn:aws:apigateway:*::/domainnames/*'
434
- ]
435
- }
436
- ];
437
-
438
- template.Resources.FriggCoreDeploymentPolicy = {
439
- Type: 'AWS::IAM::ManagedPolicy',
440
- Properties: {
441
- ManagedPolicyName: 'FriggCoreDeploymentPolicy',
442
- Description: 'Core permissions for deploying Frigg applications',
443
- PolicyDocument: {
444
- Version: '2012-10-17',
445
- Statement: coreStatements
446
- }
447
- }
448
- };
449
-
450
- // Add feature-specific policies only if needed
451
- if (features.vpc) {
452
- template.Resources.FriggVPCPolicy = {
453
- Type: 'AWS::IAM::ManagedPolicy',
454
- Condition: 'CreateVPCPermissions',
455
- Properties: {
456
- ManagedPolicyName: 'FriggVPCPolicy',
457
- Description: 'VPC-related permissions for Frigg applications',
458
- PolicyDocument: {
459
- Version: '2012-10-17',
460
- Statement: [
461
- {
462
- Sid: 'FriggVPCEndpointManagement',
463
- Effect: 'Allow',
464
- Action: [
465
- 'ec2:CreateVpcEndpoint',
466
- 'ec2:DeleteVpcEndpoint',
467
- 'ec2:DescribeVpcEndpoints',
468
- 'ec2:ModifyVpcEndpoint',
469
- 'ec2:CreateNatGateway',
470
- 'ec2:DeleteNatGateway',
471
- 'ec2:DescribeNatGateways',
472
- 'ec2:AllocateAddress',
473
- 'ec2:ReleaseAddress',
474
- 'ec2:DescribeAddresses',
475
- 'ec2:CreateRouteTable',
476
- 'ec2:DeleteRouteTable',
477
- 'ec2:DescribeRouteTables',
478
- 'ec2:CreateRoute',
479
- 'ec2:DeleteRoute',
480
- 'ec2:AssociateRouteTable',
481
- 'ec2:DisassociateRouteTable',
482
- 'ec2:CreateSecurityGroup',
483
- 'ec2:DeleteSecurityGroup',
484
- 'ec2:AuthorizeSecurityGroupEgress',
485
- 'ec2:AuthorizeSecurityGroupIngress',
486
- 'ec2:RevokeSecurityGroupEgress',
487
- 'ec2:RevokeSecurityGroupIngress'
488
- ],
489
- Resource: '*',
490
- Condition: {
491
- StringLike: {
492
- 'ec2:CreateAction': [
493
- 'CreateVpcEndpoint',
494
- 'CreateNatGateway',
495
- 'CreateRouteTable',
496
- 'CreateRoute',
497
- 'CreateSecurityGroup'
498
- ]
499
- }
500
- }
501
- }
502
- ]
503
- }
504
- }
505
- };
506
- }
507
-
508
- if (features.kms) {
509
- template.Resources.FriggKMSPolicy = {
510
- Type: 'AWS::IAM::ManagedPolicy',
511
- Condition: 'CreateKMSPermissions',
512
- Properties: {
513
- ManagedPolicyName: 'FriggKMSPolicy',
514
- Description: 'KMS encryption permissions for Frigg applications',
515
- PolicyDocument: {
516
- Version: '2012-10-17',
517
- Statement: [
518
- {
519
- Sid: 'FriggKMSEncryptionRuntime',
520
- Effect: 'Allow',
521
- Action: [
522
- 'kms:GenerateDataKey',
523
- 'kms:Decrypt'
524
- ],
525
- Resource: [
526
- { 'Fn::Sub': 'arn:aws:kms:*:${AWS::AccountId}:key/*' }
527
- ],
528
- Condition: {
529
- StringEquals: {
530
- 'kms:ViaService': [
531
- 'lambda.*.amazonaws.com',
532
- 's3.*.amazonaws.com'
533
- ]
534
- }
535
- }
536
- }
537
- ]
538
- }
539
- }
540
- };
541
- }
542
-
543
- if (features.ssm) {
544
- template.Resources.FriggSSMPolicy = {
545
- Type: 'AWS::IAM::ManagedPolicy',
546
- Condition: 'CreateSSMPermissions',
547
- Properties: {
548
- ManagedPolicyName: 'FriggSSMPolicy',
549
- Description: 'SSM Parameter Store permissions for Frigg applications',
550
- PolicyDocument: {
551
- Version: '2012-10-17',
552
- Statement: [
553
- {
554
- Sid: 'FriggSSMParameterAccess',
555
- Effect: 'Allow',
556
- Action: [
557
- 'ssm:GetParameter',
558
- 'ssm:GetParameters',
559
- 'ssm:GetParametersByPath'
560
- ],
561
- Resource: [
562
- { 'Fn::Sub': 'arn:aws:ssm:*:${AWS::AccountId}:parameter/*frigg*' },
563
- { 'Fn::Sub': 'arn:aws:ssm:*:${AWS::AccountId}:parameter/*frigg*/*' }
564
- ]
565
- }
566
- ]
567
- }
568
- }
569
- };
570
- }
571
-
572
- // Add Secrets Manager for credentials
573
- template.Resources.FriggDeploymentCredentials = {
574
- Type: 'AWS::SecretsManager::Secret',
575
- Properties: {
576
- Name: 'frigg-deployment-credentials',
577
- Description: 'Access credentials for Frigg deployment user',
578
- SecretString: {
579
- 'Fn::Sub': JSON.stringify({
580
- AccessKeyId: '${FriggDeploymentAccessKey}',
581
- SecretAccessKey: '${FriggDeploymentAccessKey.SecretAccessKey}'
582
- })
583
- }
584
- }
585
- };
586
-
587
- // Add Outputs
588
- template.Outputs = {
589
- DeploymentUserArn: {
590
- Description: 'ARN of the Frigg deployment user',
591
- Value: { 'Fn::GetAtt': ['FriggDeploymentUser', 'Arn'] },
592
- Export: {
593
- Name: { 'Fn::Sub': '${AWS::StackName}-UserArn' }
594
- }
595
- },
596
- AccessKeyId: {
597
- Description: 'Access Key ID for the deployment user',
598
- Value: { Ref: 'FriggDeploymentAccessKey' },
599
- Export: {
600
- Name: { 'Fn::Sub': '${AWS::StackName}-AccessKeyId' }
601
- }
602
- },
603
- SecretAccessKeyCommand: {
604
- Description: 'Command to retrieve the secret access key',
605
- Value: {
606
- 'Fn::Sub': 'aws secretsmanager get-secret-value --secret-id frigg-deployment-credentials --query SecretString --output text | jq -r .SecretAccessKey'
607
- }
608
- },
609
- CredentialsSecretArn: {
610
- Description: 'ARN of the secret containing deployment credentials',
611
- Value: { Ref: 'FriggDeploymentCredentials' },
612
- Export: {
613
- Name: { 'Fn::Sub': '${AWS::StackName}-CredentialsSecretArn' }
614
- }
615
- }
616
- };
617
-
618
- // Convert to YAML
619
- return convertToYAML(template);
620
- }
621
-
622
- /**
623
- * Convert JavaScript object to CloudFormation YAML
624
- * @param {Object} obj - JavaScript object
625
- * @returns {string} YAML string
626
- */
627
- function convertToYAML(obj) {
628
- const yaml = require('js-yaml');
629
- return yaml.dump(obj, {
630
- indent: 2,
631
- lineWidth: 120,
632
- noRefs: true,
633
- sortKeys: false
634
- });
635
- }
636
-
637
- /**
638
- * Generate summary of what features will be included in the IAM policy
639
- * @param {Object} appDefinition - Application definition
640
- * @returns {Object} Feature summary
641
- */
642
- function getFeatureSummary(appDefinition) {
643
- const features = {
644
- core: true, // Always enabled
645
- vpc: appDefinition.vpc?.enable === true,
646
- kms: appDefinition.encryption?.useDefaultKMSForFieldLevelEncryption === true,
647
- ssm: appDefinition.ssm?.enable === true,
648
- websockets: appDefinition.websockets?.enable === true
649
- };
650
-
651
- const integrationCount = appDefinition.integrations?.length || 0;
652
-
653
- return {
654
- features,
655
- integrationCount,
656
- appName: appDefinition.name || 'Unnamed Frigg App'
657
- };
658
- }
659
-
660
- /**
661
- * Generate basic IAM policy (JSON format) - Core Frigg permissions only
662
- * @returns {Object} Basic IAM policy document
663
- */
664
- function generateBasicIAMPolicy() {
665
- const basicPolicyPath = path.join(__dirname, 'iam-policy-basic.json');
666
- return require(basicPolicyPath);
667
- }
668
-
669
- /**
670
- * Generate full IAM policy (JSON format) - All features enabled
671
- * @returns {Object} Full IAM policy document
672
- */
673
- function generateFullIAMPolicy() {
674
- const fullPolicyPath = path.join(__dirname, 'iam-policy-full.json');
675
- return require(fullPolicyPath);
676
- }
677
-
678
- /**
679
- * Generate IAM policy based on mode
680
- * @param {string} mode - 'basic' or 'full'
681
- * @returns {Object} IAM policy document
682
- */
683
- function generateIAMPolicy(mode = 'basic') {
684
- if (mode === 'full') {
685
- return generateFullIAMPolicy();
686
- }
687
- return generateBasicIAMPolicy();
688
- }
689
-
690
- module.exports = {
691
- generateIAMCloudFormation,
692
- getFeatureSummary,
693
- generateBasicIAMPolicy,
694
- generateFullIAMPolicy,
695
- generateIAMPolicy
696
- };