cdk-factory 0.7.26__tar.gz → 0.7.28__tar.gz

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 (130) hide show
  1. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/PKG-INFO +1 -1
  2. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/pyproject.toml +1 -1
  3. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/resources/apigateway_route_config.py +1 -1
  4. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack_library/api_gateway/api_gateway_stack.py +50 -100
  5. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/utilities/api_gateway_integration_utility.py +195 -137
  6. cdk_factory-0.7.28/src/cdk_factory/version.py +1 -0
  7. cdk_factory-0.7.26/src/cdk_factory/version.py +0 -1
  8. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/.gitignore +0 -0
  9. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/LICENSE +0 -0
  10. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/README.md +0 -0
  11. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/archive/README.md +0 -0
  12. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/archive/migrate_to_enhanced_ssm.py +0 -0
  13. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/mypy.ini +0 -0
  14. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/publish_to_pypi.py +0 -0
  15. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/publish_to_pypi.sh +0 -0
  16. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/pysetup.py +0 -0
  17. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/pysetup.sh +0 -0
  18. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/requirements.dev.txt +0 -0
  19. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/requirements.tests.txt +0 -0
  20. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/requirements.txt +0 -0
  21. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/run-checks.sh +0 -0
  22. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/run-tests.sh +0 -0
  23. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/__init__.py +0 -0
  24. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/app.py +0 -0
  25. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/builds/README.md +0 -0
  26. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/cdk.json +0 -0
  27. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/commands/command_loader.py +0 -0
  28. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/base_config.py +0 -0
  29. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/cdk_config.py +0 -0
  30. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/deployment.py +0 -0
  31. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/deployment_wave.py +0 -0
  32. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/devops.py +0 -0
  33. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/enhanced_base_config.py +0 -0
  34. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/enhanced_ssm_config.py +0 -0
  35. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/management.py +0 -0
  36. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/pipeline.py +0 -0
  37. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/pipeline_stage.py +0 -0
  38. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/resources/_resources.py +0 -0
  39. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/resources/api_gateway.py +0 -0
  40. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/resources/auto_scaling.py +0 -0
  41. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/resources/cloudfront.py +0 -0
  42. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/resources/cloudwatch_widget.py +0 -0
  43. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/resources/code_artifact.py +0 -0
  44. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/resources/code_artifact_login.py +0 -0
  45. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/resources/code_repository.py +0 -0
  46. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/resources/cognito.py +0 -0
  47. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/resources/docker.py +0 -0
  48. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/resources/dynamodb.py +0 -0
  49. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/resources/ecr.py +0 -0
  50. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/resources/exisiting.py +0 -0
  51. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/resources/lambda_function.py +0 -0
  52. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/resources/lambda_layers.py +0 -0
  53. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/resources/lambda_triggers.py +0 -0
  54. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/resources/load_balancer.py +0 -0
  55. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/resources/rds.py +0 -0
  56. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/resources/resource_mapping.py +0 -0
  57. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/resources/resource_naming.py +0 -0
  58. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/resources/resource_types.py +0 -0
  59. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/resources/route53.py +0 -0
  60. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/resources/route53_hosted_zone.py +0 -0
  61. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/resources/s3.py +0 -0
  62. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/resources/security_group.py +0 -0
  63. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/resources/security_group_full_stack.py +0 -0
  64. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/resources/sqs.py +0 -0
  65. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/resources/vpc.py +0 -0
  66. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/stack.py +0 -0
  67. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/configurations/workload.py +0 -0
  68. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/constructs/cloudfront/cloudfront_distribution_construct.py +0 -0
  69. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/constructs/ecr/ecr_construct.py +0 -0
  70. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/constructs/lambdas/lambda_function_construct.py +0 -0
  71. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/constructs/lambdas/lambda_function_docker_construct.py +0 -0
  72. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/constructs/lambdas/lambda_function_role_construct.py +0 -0
  73. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/constructs/lambdas/policies/policy_docs.py +0 -0
  74. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/constructs/lambdas/policies/policy_statements.py +0 -0
  75. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/constructs/s3_buckets/s3_bucket_construct.py +0 -0
  76. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/constructs/s3_buckets/s3_bucket_replication_destination_construct.py +0 -0
  77. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/constructs/s3_buckets/s3_bucket_replication_source_construct.py +0 -0
  78. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/constructs/sqs/policies/sqs_policies.py +0 -0
  79. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/interfaces/enhanced_ssm_parameter_mixin.py +0 -0
  80. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/interfaces/istack.py +0 -0
  81. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/interfaces/live_ssm_resolver.py +0 -0
  82. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/interfaces/ssm_parameter_mixin.py +0 -0
  83. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/lambdas/health_handler.py +0 -0
  84. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/pipeline/pipeline_factory.py +0 -0
  85. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/pipeline/security/policies.py +0 -0
  86. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/pipeline/security/roles.py +0 -0
  87. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/pipeline/stage.py +0 -0
  88. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack/istack.py +0 -0
  89. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack/stack_factory.py +0 -0
  90. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack/stack_module_loader.py +0 -0
  91. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack/stack_module_registry.py +0 -0
  92. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack/stack_modules.py +0 -0
  93. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack_library/__init__.py +0 -0
  94. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack_library/auto_scaling/__init__.py +0 -0
  95. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack_library/auto_scaling/auto_scaling_stack.py +0 -0
  96. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack_library/aws_lambdas/lambda_stack.py +0 -0
  97. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack_library/buckets/README.md +0 -0
  98. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack_library/buckets/bucket_stack.py +0 -0
  99. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack_library/code_artifact/code_artifact_stack.py +0 -0
  100. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack_library/cognito/cognito_stack.py +0 -0
  101. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack_library/dynamodb/dynamodb_stack.py +0 -0
  102. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack_library/ecr/README.md +0 -0
  103. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack_library/ecr/ecr_stack.py +0 -0
  104. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack_library/load_balancer/__init__.py +0 -0
  105. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack_library/load_balancer/load_balancer_stack.py +0 -0
  106. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack_library/rds/__init__.py +0 -0
  107. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack_library/rds/rds_stack.py +0 -0
  108. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack_library/route53/__init__.py +0 -0
  109. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack_library/route53/route53_stack.py +0 -0
  110. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack_library/security_group/__init__.py +0 -0
  111. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack_library/security_group/security_group_full_stack.py +0 -0
  112. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack_library/security_group/security_group_stack.py +0 -0
  113. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack_library/simple_queue_service/sqs_stack.py +0 -0
  114. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack_library/stack_base.py +0 -0
  115. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack_library/vpc/__init__.py +0 -0
  116. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack_library/vpc/vpc_stack.py +0 -0
  117. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stack_library/websites/static_website_stack.py +0 -0
  118. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/stages/websites/static_website_stage.py +0 -0
  119. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/utilities/commandline_args.py +0 -0
  120. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/utilities/configuration_loader.py +0 -0
  121. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/utilities/docker_utilities.py +0 -0
  122. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/utilities/environment_services.py +0 -0
  123. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/utilities/file_operations.py +0 -0
  124. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/utilities/git_utilities.py +0 -0
  125. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/utilities/json_loading_utility.py +0 -0
  126. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/utilities/lambda_function_utilities.py +0 -0
  127. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/utilities/os_execute.py +0 -0
  128. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/utils/api_gateway_utilities.py +0 -0
  129. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/cdk_factory/workload/workload_factory.py +0 -0
  130. {cdk_factory-0.7.26 → cdk_factory-0.7.28}/src/handlers/test/handler.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cdk_factory
3
- Version: 0.7.26
3
+ Version: 0.7.28
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
@@ -33,7 +33,7 @@ markers = [
33
33
  [project]
34
34
 
35
35
  name = "cdk_factory"
36
- version = "0.7.26"
36
+ version = "0.7.28"
37
37
  authors = [
38
38
  { name="Eric Wilson", email="eric.wilson@geekcafe.com" }
39
39
  ]
@@ -72,7 +72,7 @@ class ApiGatewayConfigRouteConfig:
72
72
  @property
73
73
  def allow_public_override(self) -> bool:
74
74
  """Whether to allow public access when Cognito is available"""
75
- return self._config.get("allow_public_override", False)
75
+ return str(self._config.get("allow_public_override", False)).lower() == "true"
76
76
 
77
77
  @property
78
78
  def dictionary(self) -> Dict[str, Any]:
@@ -349,122 +349,60 @@ class ApiGatewayStack(IStack, EnhancedSsmParameterMixin):
349
349
 
350
350
  def _validate_authorization_configuration(self, route, has_cognito_authorizer):
351
351
  """
352
- Validate authorization configuration for security and clarity.
352
+ Validate authorization configuration using the shared utility method.
353
353
 
354
- This method implements 'secure by default' with explicit overrides:
355
- - If Cognito is available and route wants NONE auth, requires explicit override
356
- - If Cognito is not available and route wants COGNITO auth, raises error
357
- - Provides verbose warnings for monitoring and security awareness
358
-
359
- Args:
360
- route (dict): Route configuration
361
- has_cognito_authorizer (bool): Whether a Cognito authorizer is configured
362
-
363
- Raises:
364
- ValueError: When there are security conflicts without explicit overrides
354
+ This delegates to the ApiGatewayIntegrationUtility for consistent validation
355
+ across both API Gateway stack and Lambda stack patterns.
365
356
  """
366
- import logging
367
-
368
- auth_type = route.get("authorization_type", "COGNITO")
369
- explicit_override = route.get("allow_public_override", False)
370
- route_path = route.get("path", "unknown")
371
- method = route.get("method", "unknown")
357
+ # Convert route dict to ApiGatewayConfigRouteConfig for utility validation
358
+ # Map "path" to "route" for compatibility with the config object
359
+ route_config_dict = dict(route) # Create a copy
360
+ if "path" in route_config_dict:
361
+ route_config_dict["route"] = route_config_dict["path"]
372
362
 
373
- logger = logging.getLogger(__name__)
374
-
375
- # Case 1: Cognito available + NONE requested + No explicit override = ERROR
376
- if has_cognito_authorizer and auth_type == "NONE" and not explicit_override:
377
- error_msg = (
378
- f"🚨 SECURITY CONFLICT DETECTED for route {route_path} ({method}):\n"
379
- f" ❌ Cognito authorizer is configured (manual or auto-import)\n"
380
- f" ❌ authorization_type is set to 'NONE' (public access)\n"
381
- f" ❌ This creates a security risk - public endpoint with auth available\n\n"
382
- f"💡 SOLUTIONS:\n"
383
- f" 1. Remove Cognito configuration if you want public access\n"
384
- f" 2. Add 'allow_public_override': true to explicitly allow public access\n"
385
- f" 3. Remove 'authorization_type': 'NONE' to use secure Cognito auth\n\n"
386
- f"🔒 This prevents accidental public endpoints when authentication is available."
387
- )
388
- raise ValueError(error_msg)
363
+ api_route_config = ApiGatewayConfigRouteConfig(route_config_dict)
389
364
 
390
- # Case 2: No Cognito + COGNITO explicitly requested = ERROR
391
- # Only error if COGNITO was explicitly requested, not if it's the default
392
- if not has_cognito_authorizer and route.get("authorization_type") == "COGNITO":
393
- error_msg = (
394
- f"🚨 CONFIGURATION ERROR for route {route_path} ({method}):\n"
395
- f" ❌ authorization_type is explicitly set to 'COGNITO' but no Cognito authorizer configured\n"
396
- f" ❌ Cannot secure endpoint without authentication provider\n\n"
397
- f"💡 SOLUTIONS:\n"
398
- f" 1. Add Cognito configuration to enable authentication\n"
399
- f" 2. Set authorization_type to 'NONE' for public access\n"
400
- f" 3. Configure SSM auto-import for user_pool_arn\n"
401
- f" 4. Remove explicit authorization_type to use default behavior"
402
- )
403
- raise ValueError(error_msg)
404
-
405
- # Case 3: Cognito available + NONE requested + Explicit override = WARN
406
- if has_cognito_authorizer and auth_type == "NONE" and explicit_override:
407
- warning_msg = (
408
- f"⚠️ PUBLIC ENDPOINT CONFIGURED: {route_path} ({method})\n"
409
- f" 🔓 This endpoint is intentionally public (allow_public_override: true)\n"
410
- f" 🔐 Cognito authentication is available but overridden\n"
411
- f" 📊 Consider monitoring this endpoint for unexpected usage patterns\n"
412
- f" 🔍 Review periodically: Should this endpoint be secured?"
413
- )
414
-
415
- # Print to console during deployment for visibility
416
- print(warning_msg)
417
-
418
- # Structured logging for monitoring and metrics
419
- logger.warning(
420
- "Public endpoint configured with Cognito available",
421
- extra={
422
- "route": route_path,
423
- "method": method,
424
- "security_override": True,
425
- "cognito_available": True,
426
- "authorization_type": "NONE",
427
- "metric_name": "public_endpoint_with_cognito",
428
- "security_decision": "intentional_public",
429
- "recommendation": "review_periodically"
430
- }
431
- )
365
+ # Use the utility's enhanced validation method
366
+ validated_config = self.integration_utility._validate_and_adjust_authorization_configuration(
367
+ api_route_config, has_cognito_authorizer
368
+ )
432
369
 
433
- # Case 4: No Cognito + NONE = INFO (expected for public-only APIs)
434
- if not has_cognito_authorizer and auth_type == "NONE":
435
- logger.info(
436
- f"Public endpoint configured (no Cognito available): {route_path} ({method})",
437
- extra={
438
- "route": route_path,
439
- "method": method,
440
- "authorization_type": "NONE",
441
- "cognito_available": False,
442
- "security_decision": "public_only_api"
443
- }
444
- )
370
+ # Return the validated authorization type for use in the stack
371
+ return validated_config.authorization_type
445
372
 
446
373
  def _setup_lambda_integration(
447
374
  self, api_gateway, api_id, route, lambda_fn, authorizer, suffix
448
375
  ):
449
376
  """Setup Lambda integration for a route"""
450
- import logging
451
-
452
377
  route_path = route["path"]
453
- # Secure by default: require Cognito authorization unless explicitly set to NONE
378
+
379
+ # Handle authorization type fallback logic before validation
454
380
  authorization_type = route.get("authorization_type", "COGNITO")
455
381
 
456
382
  # If no Cognito authorizer available and default COGNITO, fall back to NONE
457
- if not authorizer and authorization_type == "COGNITO" and "authorization_type" not in route:
383
+ if (
384
+ not authorizer
385
+ and authorization_type == "COGNITO"
386
+ and "authorization_type" not in route
387
+ ):
458
388
  authorization_type = "NONE"
389
+ import logging
459
390
  logger = logging.getLogger(__name__)
460
391
  logger.info(
461
392
  f"No Cognito authorizer available for route {route_path} ({route.get('method', 'unknown')}), "
462
393
  f"defaulting to public access (NONE authorization)"
463
394
  )
464
395
 
465
- # Validate authorization configuration for security
466
- self._validate_authorization_configuration(route, authorizer is not None)
396
+ # Create a route config with the resolved authorization type for validation
397
+ route_for_validation = dict(route)
398
+ route_for_validation["authorization_type"] = authorization_type
399
+
400
+ # Validate authorization configuration using the utility
401
+ validated_authorization_type = self._validate_authorization_configuration(route_for_validation, authorizer is not None)
467
402
 
403
+ # Use the validated authorization type
404
+ authorization_type = validated_authorization_type
405
+
468
406
  # If set to NONE (explicitly or by fallback), skip authorization
469
407
  if authorization_type == "NONE":
470
408
  authorizer = None
@@ -480,6 +418,7 @@ class ApiGatewayStack(IStack, EnhancedSsmParameterMixin):
480
418
  "user_pool_id": (
481
419
  os.getenv("COGNITO_USER_POOL_ID") if authorizer else None
482
420
  ),
421
+ "allow_public_override": route.get("allow_public_override", False),
483
422
  }
484
423
  )
485
424
 
@@ -501,23 +440,34 @@ class ApiGatewayStack(IStack, EnhancedSsmParameterMixin):
501
440
  self, api_gateway, route, lambda_fn, authorizer, api_id, suffix
502
441
  ):
503
442
  """Setup fallback Lambda integration for routes without src"""
504
- import logging
505
-
506
443
  route_path = route["path"]
507
- # Secure by default: require Cognito authorization unless explicitly set to NONE
444
+
445
+ # Handle authorization type fallback logic before validation
508
446
  authorization_type = route.get("authorization_type", "COGNITO")
509
447
 
510
448
  # If no Cognito authorizer available and default COGNITO, fall back to NONE
511
- if not authorizer and authorization_type == "COGNITO" and "authorization_type" not in route:
449
+ if (
450
+ not authorizer
451
+ and authorization_type == "COGNITO"
452
+ and "authorization_type" not in route
453
+ ):
512
454
  authorization_type = "NONE"
455
+ import logging
513
456
  logger = logging.getLogger(__name__)
514
457
  logger.info(
515
458
  f"No Cognito authorizer available for route {route_path} ({route.get('method', 'unknown')}), "
516
459
  f"defaulting to public access (NONE authorization)"
517
460
  )
518
461
 
519
- # Validate authorization configuration for security
520
- self._validate_authorization_configuration(route, authorizer is not None)
462
+ # Create a route config with the resolved authorization type for validation
463
+ route_for_validation = dict(route)
464
+ route_for_validation["authorization_type"] = authorization_type
465
+
466
+ # Validate authorization configuration using the utility
467
+ validated_authorization_type = self._validate_authorization_configuration(route_for_validation, authorizer is not None)
468
+
469
+ # Use the validated authorization type
470
+ authorization_type = validated_authorization_type
521
471
 
522
472
  resource = (
523
473
  api_gateway.root.resource_for_path(route_path)