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