@friggframework/devtools 2.0.0--canary.490.48bfca6.0 → 2.0.0--canary.490.84409c6.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.
@@ -253,6 +253,24 @@ class KmsBuilder extends InfrastructureBuilder {
253
253
  if (decisions.key.ownership === ResourceOwnership.STACK && decisions.key.physicalId) {
254
254
  // Key exists in stack - add definitions (CloudFormation idempotency)
255
255
  console.log(' → Adding KMS definitions to template (existing in stack)');
256
+
257
+ // CRITICAL: Check if alias exists in stack before trying to create it
258
+ // Matches old serverless-template.js behavior: only create alias if it doesn't exist
259
+ const aliasExistsInStack = discoveredResources?.existingLogicalIds?.includes('FriggKMSKeyAlias');
260
+ if (!aliasExistsInStack) {
261
+ if (appDefinition.encryption?.kmsKeyAlias !== true) {
262
+ // Alias doesn't exist in stack - skip creation unless explicitly enabled
263
+ // This avoids kms:CreateAlias permission errors
264
+ console.log(' ℹ KMS alias not in stack - skipping creation (set kmsKeyAlias: true to force)');
265
+ appDefinition.encryption = appDefinition.encryption || {};
266
+ appDefinition.encryption.kmsKeyAlias = false;
267
+ } else {
268
+ console.log(' → Will create KMS alias (kmsKeyAlias: true explicitly set)');
269
+ }
270
+ } else {
271
+ console.log(' ✓ KMS alias found in stack - will keep in template');
272
+ }
273
+
256
274
  result.resources = this.createKmsKey(appDefinition);
257
275
  result.environment.KMS_KEY_ARN = { 'Fn::GetAtt': ['FriggKMSKey', 'Arn'] };
258
276
  console.log(' ✅ KMS key resources created');
@@ -270,6 +288,17 @@ class KmsBuilder extends InfrastructureBuilder {
270
288
  } else if (decisions.key.ownership === ResourceOwnership.STACK && !decisions.key.physicalId && !useEnvVarFallback) {
271
289
  // Create new KMS key (only if not using env var fallback and no external key found)
272
290
  console.log(' → Creating new KMS key in stack');
291
+
292
+ // CRITICAL: Don't create alias by default to avoid kms:CreateAlias permission errors
293
+ // Matches old serverless-template.js behavior: only create alias if explicitly requested
294
+ if (appDefinition.encryption?.kmsKeyAlias !== true) {
295
+ console.log(' ℹ Skipping KMS alias creation by default (set kmsKeyAlias: true to enable)');
296
+ appDefinition.encryption = appDefinition.encryption || {};
297
+ appDefinition.encryption.kmsKeyAlias = false;
298
+ } else {
299
+ console.log(' → Will create KMS alias (kmsKeyAlias: true explicitly set)');
300
+ }
301
+
273
302
  result.resources = this.createKmsKey(appDefinition);
274
303
  result.environment.KMS_KEY_ARN = { 'Fn::GetAtt': ['FriggKMSKey', 'Arn'] };
275
304
  console.log(' ✅ KMS key resources created');
@@ -307,7 +336,7 @@ class KmsBuilder extends InfrastructureBuilder {
307
336
  * Create KMS key CloudFormation resources
308
337
  */
309
338
  createKmsKey(appDefinition) {
310
- return {
339
+ const resources = {
311
340
  FriggKMSKey: {
312
341
  Type: 'AWS::KMS::Key',
313
342
  DeletionPolicy: 'Retain',
@@ -361,15 +390,24 @@ class KmsBuilder extends InfrastructureBuilder {
361
390
  ],
362
391
  },
363
392
  },
364
- FriggKMSKeyAlias: {
393
+ };
394
+
395
+ // Only create alias if explicitly enabled (default: true for backwards compatibility)
396
+ const createAlias = appDefinition.encryption?.kmsKeyAlias !== false;
397
+ if (createAlias) {
398
+ resources.FriggKMSKeyAlias = {
365
399
  Type: 'AWS::KMS::Alias',
366
400
  DeletionPolicy: 'Retain',
367
401
  Properties: {
368
402
  AliasName: 'alias/${self:service}-${self:provider.stage}-frigg-kms',
369
403
  TargetKeyId: { 'Fn::GetAtt': ['FriggKMSKey', 'Arn'] },
370
404
  },
371
- },
372
- };
405
+ };
406
+ } else {
407
+ console.log(' ℹ Skipping KMS key alias creation (kmsKeyAlias: false)');
408
+ }
409
+
410
+ return resources;
373
411
  }
374
412
  }
375
413
 
@@ -209,11 +209,12 @@ describe('KmsBuilder', () => {
209
209
  expect(result.resources.FriggKMSKey.Type).toBe('AWS::KMS::Key');
210
210
  });
211
211
 
212
- it('should create KMS key alias', async () => {
212
+ it('should create KMS key alias when explicitly enabled', async () => {
213
213
  const appDefinition = {
214
214
  encryption: {
215
215
  fieldLevelEncryptionMethod: 'kms',
216
216
  createResourceIfNoneFound: true,
217
+ kmsKeyAlias: true, // Explicitly enable alias creation
217
218
  },
218
219
  };
219
220
 
@@ -225,6 +226,23 @@ describe('KmsBuilder', () => {
225
226
  expect(result.resources.FriggKMSKeyAlias.Type).toBe('AWS::KMS::Alias');
226
227
  });
227
228
 
229
+ it('should skip alias creation when kmsKeyAlias: false', async () => {
230
+ const appDefinition = {
231
+ encryption: {
232
+ fieldLevelEncryptionMethod: 'kms',
233
+ createResourceIfNoneFound: true,
234
+ kmsKeyAlias: false,
235
+ },
236
+ };
237
+
238
+ const discoveredResources = {};
239
+
240
+ const result = await kmsBuilder.build(appDefinition, discoveredResources);
241
+
242
+ expect(result.resources.FriggKMSKey).toBeDefined();
243
+ expect(result.resources.FriggKMSKeyAlias).toBeUndefined();
244
+ });
245
+
228
246
  it('should enable key rotation for new keys', async () => {
229
247
  const appDefinition = {
230
248
  encryption: {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@friggframework/devtools",
3
3
  "prettier": "@friggframework/prettier-config",
4
- "version": "2.0.0--canary.490.48bfca6.0",
4
+ "version": "2.0.0--canary.490.84409c6.0",
5
5
  "bin": {
6
6
  "frigg": "./frigg-cli/index.js"
7
7
  },
@@ -16,9 +16,9 @@
16
16
  "@babel/eslint-parser": "^7.18.9",
17
17
  "@babel/parser": "^7.25.3",
18
18
  "@babel/traverse": "^7.25.3",
19
- "@friggframework/core": "2.0.0--canary.490.48bfca6.0",
20
- "@friggframework/schemas": "2.0.0--canary.490.48bfca6.0",
21
- "@friggframework/test": "2.0.0--canary.490.48bfca6.0",
19
+ "@friggframework/core": "2.0.0--canary.490.84409c6.0",
20
+ "@friggframework/schemas": "2.0.0--canary.490.84409c6.0",
21
+ "@friggframework/test": "2.0.0--canary.490.84409c6.0",
22
22
  "@hapi/boom": "^10.0.1",
23
23
  "@inquirer/prompts": "^5.3.8",
24
24
  "axios": "^1.7.2",
@@ -46,8 +46,8 @@
46
46
  "validate-npm-package-name": "^5.0.0"
47
47
  },
48
48
  "devDependencies": {
49
- "@friggframework/eslint-config": "2.0.0--canary.490.48bfca6.0",
50
- "@friggframework/prettier-config": "2.0.0--canary.490.48bfca6.0",
49
+ "@friggframework/eslint-config": "2.0.0--canary.490.84409c6.0",
50
+ "@friggframework/prettier-config": "2.0.0--canary.490.84409c6.0",
51
51
  "aws-sdk-client-mock": "^4.1.0",
52
52
  "aws-sdk-client-mock-jest": "^4.1.0",
53
53
  "jest": "^30.1.3",
@@ -79,5 +79,5 @@
79
79
  "publishConfig": {
80
80
  "access": "public"
81
81
  },
82
- "gitHead": "48bfca6d78f99b7b5aec094ed40e969efdda02a4"
82
+ "gitHead": "84409c6304ea14a6b9789ed8fc9ca07fe2385b17"
83
83
  }