cdk-factory 0.7.24__py3-none-any.whl → 0.7.26__py3-none-any.whl

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.

Potentially problematic release.


This version of cdk-factory might be problematic. Click here for more details.

@@ -68,3 +68,13 @@ class ApiGatewayConfigRouteConfig:
68
68
  def user_pool_id(self) -> str | None:
69
69
  """User pool ID for existing authorizers"""
70
70
  return self._config.get("user_pool_id")
71
+
72
+ @property
73
+ def allow_public_override(self) -> bool:
74
+ """Whether to allow public access when Cognito is available"""
75
+ return self._config.get("allow_public_override", False)
76
+
77
+ @property
78
+ def dictionary(self) -> Dict[str, Any]:
79
+ """Access to the underlying configuration dictionary"""
80
+ return self._config
@@ -54,6 +54,17 @@ class ApiGatewayIntegrationUtility:
54
54
  if not api_config:
55
55
  raise ValueError("API Gateway config is missing in Lambda function config")
56
56
 
57
+ # Validate authorization configuration for security
58
+ has_cognito_authorizer = (
59
+ self.authorizer is not None or
60
+ self._get_existing_authorizer_id_with_ssm_fallback(api_config, stack_config) is not None
61
+ )
62
+
63
+ # Apply enhanced authorization validation and fallback logic
64
+ api_config = self._validate_and_adjust_authorization_configuration(
65
+ api_config, has_cognito_authorizer
66
+ )
67
+
57
68
  # Get or create authorizer if needed (only for COGNITO_USER_POOLS authorization)
58
69
  if api_config.authorization_type != "NONE" and not self.authorizer:
59
70
  self.authorizer = self.get_or_create_authorizer(
@@ -1294,3 +1305,126 @@ class ApiGatewayIntegrationUtility:
1294
1305
  api_gateways[api_key]['integrations'].append(integration)
1295
1306
 
1296
1307
  return api_gateways
1308
+
1309
+ def _validate_and_adjust_authorization_configuration(
1310
+ self, api_config: ApiGatewayConfigRouteConfig, has_cognito_authorizer: bool
1311
+ ) -> ApiGatewayConfigRouteConfig:
1312
+ """
1313
+ Validate and adjust authorization configuration for security and clarity.
1314
+
1315
+ This method implements 'secure by default' with explicit overrides:
1316
+ - If Cognito is available and route wants NONE auth, requires explicit override
1317
+ - If Cognito is not available and route wants COGNITO auth, raises error
1318
+ - Provides verbose warnings for monitoring and security awareness
1319
+ - Returns a potentially modified api_config with adjusted authorization_type
1320
+
1321
+ Args:
1322
+ api_config (ApiGatewayConfigRouteConfig): Route configuration
1323
+ has_cognito_authorizer (bool): Whether a Cognito authorizer is configured
1324
+
1325
+ Returns:
1326
+ ApiGatewayConfigRouteConfig: Potentially modified configuration
1327
+
1328
+ Raises:
1329
+ ValueError: When there are security conflicts without explicit overrides
1330
+ """
1331
+ import logging
1332
+ from copy import deepcopy
1333
+
1334
+ # Create a copy to avoid modifying the original
1335
+ modified_config = deepcopy(api_config)
1336
+
1337
+ auth_type = getattr(api_config, 'authorization_type', 'COGNITO')
1338
+
1339
+ # Check for explicit override flag
1340
+ explicit_override = getattr(api_config, 'allow_public_override', False)
1341
+
1342
+ route_path = getattr(api_config, 'routes', 'unknown')
1343
+ method = getattr(api_config, 'method', 'unknown')
1344
+
1345
+ logger = logging.getLogger(__name__)
1346
+
1347
+ # Case 1: Cognito available + NONE requested + No explicit override = ERROR
1348
+ if has_cognito_authorizer and auth_type == "NONE" and not explicit_override:
1349
+ error_msg = (
1350
+ f"🚨 SECURITY CONFLICT DETECTED for route {route_path} ({method}):\n"
1351
+ f" ❌ Cognito authorizer is configured (manual or auto-import)\n"
1352
+ f" ❌ authorization_type is set to 'NONE' (public access)\n"
1353
+ f" ❌ This creates a security risk - public endpoint with auth available\n\n"
1354
+ f"💡 SOLUTIONS:\n"
1355
+ f" 1. Remove Cognito configuration if you want public access\n"
1356
+ f" 2. Add 'allow_public_override': true to explicitly allow public access\n"
1357
+ f" 3. Remove 'authorization_type': 'NONE' to use secure Cognito auth\n\n"
1358
+ f"🔒 This prevents accidental public endpoints when authentication is available."
1359
+ )
1360
+ raise ValueError(error_msg)
1361
+
1362
+ # Case 2: No Cognito + COGNITO explicitly requested = ERROR
1363
+ # Only error if COGNITO was explicitly requested, not if it's the default
1364
+ original_auth_type = None
1365
+ if hasattr(api_config, 'dictionary') and api_config.dictionary:
1366
+ original_auth_type = api_config.dictionary.get('authorization_type')
1367
+
1368
+ if not has_cognito_authorizer and original_auth_type == "COGNITO":
1369
+ error_msg = (
1370
+ f"🚨 CONFIGURATION ERROR for route {route_path} ({method}):\n"
1371
+ f" ❌ authorization_type is explicitly set to 'COGNITO' but no Cognito authorizer configured\n"
1372
+ f" ❌ Cannot secure endpoint without authentication provider\n\n"
1373
+ f"💡 SOLUTIONS:\n"
1374
+ f" 1. Add Cognito configuration to enable authentication\n"
1375
+ f" 2. Set authorization_type to 'NONE' for public access\n"
1376
+ f" 3. Configure SSM auto-import for user_pool_arn\n"
1377
+ f" 4. Remove explicit authorization_type to use default behavior"
1378
+ )
1379
+ raise ValueError(error_msg)
1380
+
1381
+ # Case 3: Cognito available + NONE requested + Explicit override = WARN
1382
+ if has_cognito_authorizer and auth_type == "NONE" and explicit_override:
1383
+ warning_msg = (
1384
+ f"⚠️ PUBLIC ENDPOINT CONFIGURED: {route_path} ({method})\n"
1385
+ f" 🔓 This endpoint is intentionally public (allow_public_override: true)\n"
1386
+ f" 🔐 Cognito authentication is available but overridden\n"
1387
+ f" 📊 Consider monitoring this endpoint for unexpected usage patterns\n"
1388
+ f" 🔍 Review periodically: Should this endpoint be secured?"
1389
+ )
1390
+
1391
+ # Print to console during deployment for visibility
1392
+ print(warning_msg)
1393
+
1394
+ # Structured logging for monitoring and metrics
1395
+ logger.warning(
1396
+ "Public endpoint configured with Cognito available",
1397
+ extra={
1398
+ "route": route_path,
1399
+ "method": method,
1400
+ "security_override": True,
1401
+ "cognito_available": True,
1402
+ "authorization_type": "NONE",
1403
+ "metric_name": "public_endpoint_with_cognito",
1404
+ "security_decision": "intentional_public",
1405
+ "recommendation": "review_periodically"
1406
+ }
1407
+ )
1408
+
1409
+ # Case 4: No Cognito + default COGNITO = Fall back to NONE
1410
+ if not has_cognito_authorizer and auth_type == "COGNITO" and original_auth_type is None:
1411
+ modified_config.authorization_type = "NONE"
1412
+ logger.info(
1413
+ f"No Cognito authorizer available for route {route_path} ({method}), "
1414
+ f"defaulting to public access (NONE authorization)"
1415
+ )
1416
+
1417
+ # Case 5: No Cognito + NONE = INFO (expected for public-only APIs)
1418
+ if not has_cognito_authorizer and auth_type == "NONE":
1419
+ logger.info(
1420
+ f"Public endpoint configured (no Cognito available): {route_path} ({method})",
1421
+ extra={
1422
+ "route": route_path,
1423
+ "method": method,
1424
+ "authorization_type": "NONE",
1425
+ "cognito_available": False,
1426
+ "security_decision": "public_only_api"
1427
+ }
1428
+ )
1429
+
1430
+ return modified_config
cdk_factory/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.7.24"
1
+ __version__ = "0.7.26"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cdk_factory
3
- Version: 0.7.24
3
+ Version: 0.7.26
4
4
  Summary: CDK Factory. A QuickStarter and best practices setup for CDK projects
5
5
  Author-email: Eric Wilson <eric.wilson@geekcafe.com>
6
6
  License: MIT License
@@ -1,7 +1,7 @@
1
1
  cdk_factory/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  cdk_factory/app.py,sha256=xv863N7O6HPKznB68_t7O4la9JacrkG87t9TjoDUk7s,2827
3
3
  cdk_factory/cdk.json,sha256=SKZKhJ2PBpFH78j-F8S3VDYW-lf76--Q2I3ON-ZIQfw,3106
4
- cdk_factory/version.py,sha256=6LhdCdekRyhf1ou0xLzDta4kGS27Isdvy5haWR1XJoc,23
4
+ cdk_factory/version.py,sha256=bdHnwFVnv19lO1d9o0Rjk5Js7MqJglg3CX1USYBiklY,23
5
5
  cdk_factory/builds/README.md,sha256=9BBWd7bXpyKdMU_g2UljhQwrC9i5O_Tvkb6oPvndoZk,90
6
6
  cdk_factory/commands/command_loader.py,sha256=QbLquuP_AdxtlxlDy-2IWCQ6D-7qa58aphnDPtp_uTs,3744
7
7
  cdk_factory/configurations/base_config.py,sha256=JKjhNsy0RCUZy1s8n5D_aXXI-upR9izaLtCTfKYiV9k,9624
@@ -18,7 +18,7 @@ cdk_factory/configurations/stack.py,sha256=7whhC48dUYw7BBFV49zM1Q3AghTNkaiDfy4kK
18
18
  cdk_factory/configurations/workload.py,sha256=sM-B6UKOdOn5_H-eWmW03J9oa8YZZmO0bvQ69wbCM0Q,7756
19
19
  cdk_factory/configurations/resources/_resources.py,sha256=tnXGn4kEC0JPQaTWB3QpAZG-2hIGBtugHTzuKn1OTvE,2548
20
20
  cdk_factory/configurations/resources/api_gateway.py,sha256=-k4hMGszIdQLb5DGmWBIPy49YGutp8zczafRh-Vob0I,4904
21
- cdk_factory/configurations/resources/apigateway_route_config.py,sha256=R7ZUz8aZ37HdzL5aSqLB624KsQ7-kp713NGuBnU0x_4,1982
21
+ cdk_factory/configurations/resources/apigateway_route_config.py,sha256=fESVFKEKBj-EdkxB-iyDcA43FY1fX9Ow1QedH6UCm2I,2328
22
22
  cdk_factory/configurations/resources/auto_scaling.py,sha256=OAVl8iUdHiOYVzme1qNDwA3w2raxDNUo_W2_Vebqtx8,5005
23
23
  cdk_factory/configurations/resources/cloudfront.py,sha256=xwDIrYQDqQMgekXSJ5vrgNXIUCfY6O8aiybE5ewwijw,1055
24
24
  cdk_factory/configurations/resources/cloudwatch_widget.py,sha256=EdEQSXUkDtoY_Mg_cJBWo1Hp84jSiK7U9tsd3k1VhKI,1271
@@ -97,7 +97,7 @@ cdk_factory/stack_library/vpc/__init__.py,sha256=7pIqP97Gf2AJbv9Ebp1WbQGHYhgEbWJ
97
97
  cdk_factory/stack_library/vpc/vpc_stack.py,sha256=zdDiGilf03esxuya5Z8zVYSVMAIuZBeD-ZKgfnEd6aw,10077
98
98
  cdk_factory/stack_library/websites/static_website_stack.py,sha256=KBQiV6PI09mpHGtH-So5Hk3uhfFLDepoXInGbfin0cY,7938
99
99
  cdk_factory/stages/websites/static_website_stage.py,sha256=X4fpKXkhb0zIbSHx3QyddBhVSLBryb1vf1Cg2fMTqog,755
100
- cdk_factory/utilities/api_gateway_integration_utility.py,sha256=RdStGFueFFDR_j1zHX-d55czZKf_lP-_Ty_5-XLPQXg,55224
100
+ cdk_factory/utilities/api_gateway_integration_utility.py,sha256=QlIGmWAJShDMTy7mIJeQDyHr59jP7EKQQOFXTNCQJA4,61923
101
101
  cdk_factory/utilities/commandline_args.py,sha256=0FiNEJFbWVN8Ct7r0VHnJEx7rhUlaRKT7R7HMNJBSTI,2216
102
102
  cdk_factory/utilities/configuration_loader.py,sha256=z0ZdGLNbTO4_yfluB9zUh_i_Poc9qj-7oRyjMRlNkN8,1522
103
103
  cdk_factory/utilities/docker_utilities.py,sha256=9r8C-lXYpymqEfi3gTeWCQzHldvfjttPqn6p3j2khTE,8111
@@ -109,7 +109,7 @@ cdk_factory/utilities/lambda_function_utilities.py,sha256=j3tBdv_gC2MdEwBINDwAqY
109
109
  cdk_factory/utilities/os_execute.py,sha256=5Op0LY_8Y-pUm04y1k8MTpNrmQvcLmQHPQITEP7EuSU,1019
110
110
  cdk_factory/utils/api_gateway_utilities.py,sha256=If7Xu5s_UxmuV-kL3JkXxPLBdSVUKoLtohm0IUFoiV8,4378
111
111
  cdk_factory/workload/workload_factory.py,sha256=yBUDGIuB8-5p_mGcVFxsD2ZoZIziak3yh3LL3JvS0M4,5903
112
- cdk_factory-0.7.24.dist-info/METADATA,sha256=arpwSUyP9MEQqdJM6dkFtxxq0Q3o3PvjutwymPmzV8g,2451
113
- cdk_factory-0.7.24.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
114
- cdk_factory-0.7.24.dist-info/licenses/LICENSE,sha256=NOtdOeLwg2il_XBJdXUPFPX8JlV4dqTdDGAd2-khxT8,1066
115
- cdk_factory-0.7.24.dist-info/RECORD,,
112
+ cdk_factory-0.7.26.dist-info/METADATA,sha256=33JcY3G617lMyKEaMalJobLMN5SQdNSqCSdHp5pgeDc,2451
113
+ cdk_factory-0.7.26.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
114
+ cdk_factory-0.7.26.dist-info/licenses/LICENSE,sha256=NOtdOeLwg2il_XBJdXUPFPX8JlV4dqTdDGAd2-khxT8,1066
115
+ cdk_factory-0.7.26.dist-info/RECORD,,