1919import sra_cloudwatch
2020import sra_kms
2121
22- from typing import Dict , Any
22+ from typing import Dict , Any , List
2323
2424# import sra_lambda
2525
2626# TODO(liamschn): If dynamoDB sra_state table exists, use it
2727# TODO(liamschn): Where do we see dry-run data? Maybe S3 staging bucket file? The sra_state table? Another DynamoDB table?
28- # TODO(liamschn): add parameter validation
28+ # TODO(liamschn): add parameter validation (in progress; testing)
2929# TODO(liamschn): deploy example bedrock guardrail
30- # TODO(liamschn): deploy example iam role(s) and policy(ies) - lower priority?
31- # TODO(liamschn): deploy example bucket policy(ies) - lower priority?
30+ # TODO(liamschn): deploy example iam role(s) and policy(ies) - lower priority/not necessary?
31+ # TODO(liamschn): deploy example bucket policy(ies) - lower priority/not necessary?
32+ # TODO(liamschn): deal with linting failures in pipeline
33+ # TODO(liamschn): deal with typechecking/mypy
34+ # TODO(liamschn): check for unused parameters
3235
3336from typing import TYPE_CHECKING , Sequence # , Union, Literal, Optional
3437
@@ -74,11 +77,9 @@ def load_sra_cloudwatch_dashboard() -> dict:
7477RESOURCE_TYPE : str = ""
7578STATE_TABLE : str = "sra_state"
7679SOLUTION_NAME : str = "sra-bedrock-org"
77- # RULE_REGIONS_ACCOUNTS: list = {}
7880GOVERNED_REGIONS = []
7981SECURITY_ACCOUNT = ""
8082ORGANIZATION_ID = ""
81- # BEDROCK_MODEL_EVAL_BUCKET: str = ""
8283SRA_ALARM_EMAIL : str = ""
8384SRA_ALARM_TOPIC_ARN : str = ""
8485
@@ -105,7 +106,6 @@ def load_sra_cloudwatch_dashboard() -> dict:
105106DRY_RUN_DATA : dict = {}
106107
107108# other global variables
108- # TODO(liamschn): Urgent - cannot use these for CFN responses. Max size is 4096 bytes and this gets too large for this. Must change this ASAP (highest priority)
109109LIVE_RUN_DATA : dict = {}
110110IAM_POLICY_DOCUMENTS : Dict [str , Any ] = load_iam_policy_documents ()
111111CLOUDWATCH_METRIC_FILTERS : dict = load_cloudwatch_metric_filters ()
@@ -114,6 +114,35 @@ def load_sra_cloudwatch_dashboard() -> dict:
114114CLOUDWATCH_OAM_TRUST_POLICY : dict = load_sra_cloudwatch_oam_trust_policy ()
115115CLOUDWATCH_DASHBOARD : dict = load_sra_cloudwatch_dashboard ()
116116
117+ # Parameter validation rules
118+ PARAMETER_VALIDATION_RULES : dict = {
119+ "SRA_REPO_ZIP_URL" : r'^https://.*\.zip$' ,
120+ "DRY_RUN" : r'^true|false$' ,
121+ "EXECUTION_ROLE_NAME" : r'^sra-execution$' ,
122+ "LOG_GROUP_DEPLOY" : r'^true|false$' ,
123+ "LOG_GROUP_RETENTION" : r'^(1|3|5|7|14|30|60|90|120|150|180|365|400|545|731|1096|1827|2192|2557|2922|3288|3653)$' ,
124+ "LOG_LEVEL" : r'^(DEBUG|INFO|WARNING|ERROR|CRITICAL)$' ,
125+ "SOLUTION_NAME" : r'^sra-bedrock-org$' ,
126+ "SOLUTION_VERSION" : r'^[0-9]+\.[0-9]+\.[0-9]+$' ,
127+ "SRA_ALARM_EMAIL" : r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$' ,
128+ "SRA-BEDROCK-ACCOUNTS" : r'^\[((?:"[0-9]+"(?:\s*,\s*)?)*)\]$' ,
129+ "SRA-BEDROCK-REGIONS" : r'^\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\]$' ,
130+ "SRA-BEDROCK-CHECK-EVAL-JOB-BUCKET" : r'^\{"deploy"\s*:\s*"(true|false)",\s*"accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\],\s*"input_params"\s*:\s*(\{\s*(?:"BucketName"\s*:\s*"([a-zA-Z0-9-]*)"\s*)?})\}$' ,
131+ "SRA-BEDROCK-CHECK-IAM-USER-ACCESS" : r'^\{"deploy"\s*:\s*"(true|false)",\s*"accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\],\s*"input_params"\s*:\s*(\{\s*(?:"BucketName"\s*:\s*"([a-zA-Z0-9-]*)"\s*)?})\}$' ,
132+ "SRA-BEDROCK-CHECK-GUARDRAILS" : r'^\{"deploy"\s*:\s*"(true|false)",\s*"accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\],\s*"input_params"\s*:\s*\{(\s*"content_filters"\s*:\s*"(true|false)")?(\s*,\s*"denied_topics"\s*:\s*"(true|false)")?(\s*,\s*"word_filters"\s*:\s*"(true|false)")?(\s*,\s*"sensitive_info_filters"\s*:\s*"(true|false)")?(\s*,\s*"contextual_grounding"\s*:\s*"(true|false)")?\s*\}\}$' ,
133+ "SRA-BEDROCK-CHECK-VPC-ENDPOINTS" : r'^\{"deploy"\s*:\s*"(true|false)",\s*"accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\],\s*"input_params"\s*:\s*\{(\s*"check_bedrock"\s*:\s*"(true|false)")?(\s*,\s*"check_bedrock_agent"\s*:\s*"(true|false)")?(\s*,\s*"check_bedrock_agent_runtime"\s*:\s*"(true|false)")?(\s*,\s*"check_bedrock_runtime"\s*:\s*"(true|false)")?\s*\}\}$' ,
134+ "SRA-BEDROCK-CHECK-INVOCATION-LOG-CLOUDWATCH" : r'^\{"deploy"\s*:\s*"(true|false)",\s*"accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\],\s*"input_params"\s*:\s*\{(\s*"check_retention"\s*:\s*"(true|false)")?(\s*,\s*"check_encryption"\s*:\s*"(true|false)")?\}\}$' ,
135+ "SRA-BEDROCK-CHECK-INVOCATION-LOG-S3" : r'^\{"deploy"\s*:\s*"(true|false)",\s*"accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\],\s*"input_params"\s*:\s*\{(\s*"check_retention"\s*:\s*"(true|false)")?(\s*,\s*"check_encryption"\s*:\s*"(true|false)")?(\s*,\s*"check_access_logging"\s*:\s*"(true|false)")?(\s*,\s*"check_object_locking"\s*:\s*"(true|false)")?(\s*,\s*"check_versioning"\s*:\s*"(true|false)")?\s*\}\}$' ,
136+ "SRA-BEDROCK-CHECK-CLOUDWATCH-ENDPOINTS" : r'^\{"deploy"\s*:\s*"(true|false)",\s*"accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\],\s*"input_params"\s*:\s*(\{\})\}$' ,
137+ "SRA-BEDROCK-CHECK-S3-ENDPOINTS" : r'^\{"deploy"\s*:\s*"(true|false)",\s*"accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\],\s*"input_params"\s*:\s*(\{\})\}$' ,
138+ "SRA-BEDROCK-CHECK-GUARDRAIL-ENCRYPTION" : r'^\{"deploy"\s*:\s*"(true|false)",\s*"accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\],\s*"input_params"\s*:\s*(\{\})\}$' ,
139+ "SRA-BEDROCK-FILTER-SERVICE-CHANGES" : r'^\{"deploy"\s*:\s*"(true|false)",\s*"accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\],\s*"filter_params"\s*:\s*\{"log_group_name"\s*:\s*"[^"\s]+"\}\}$' ,
140+ "SRA-BEDROCK-FILTER-BUCKET-CHANGES" : r'^\{"deploy"\s*:\s*"(true|false)",\s*"accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\],\s*"filter_params"\s*:\s*\{"log_group_name"\s*:\s*"[^"\s]+",\s*"bucket_names"\s*:\s*\[((?:"[^"\s]+"(?:\s*,\s*)?)+)\]\}\}$' ,
141+ "SRA-BEDROCK-FILTER-PROMPT-INJECTION" : r'^\{"deploy"\s*:\s*"(true|false)",\s*"accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\],\s*"filter_params"\s*:\s*\{"log_group_name"\s*:\s*"[^"\s]+",\s*"input_path"\s*:\s*"[^"\s]+"\}\}$' ,
142+ "SRA-BEDROCK-FILTER-SENSITIVE-INFO" : r'^\{"deploy"\s*:\s*"(true|false)",\s*"accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\],\s*"filter_params"\s*:\s*\{"log_group_name"\s*:\s*"[^"\s]+",\s*"input_path"\s*:\s*"[^"\s]+"\}\}$' ,
143+ "SRA-BEDROCK-CENTRAL-OBSERVABILITY" : r'^\{"deploy"\s*:\s*"(true|false)",\s*"bedrock_accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\]\}$' ,
144+ }
145+
117146# Instantiate sra class objects
118147# todo(liamschn): can these files exist in some central location to be shared with other solutions?
119148ssm_params = sra_ssm_params .sra_ssm_params ()
@@ -133,17 +162,20 @@ def load_sra_cloudwatch_dashboard() -> dict:
133162
134163def get_resource_parameters (event ):
135164 global DRY_RUN
136- # global RULE_REGIONS_ACCOUNTS
137165 global GOVERNED_REGIONS
138- # global BEDROCK_MODEL_EVAL_BUCKET
139166 global CFN_RESPONSE_DATA
140167 global SRA_ALARM_EMAIL
141168 global SECURITY_ACCOUNT
142169 global ORGANIZATION_ID
143170
171+ param_validation : dict = validate_parameters (event ["ResourceProperties" ], PARAMETER_VALIDATION_RULES )
172+ if param_validation ["success" ] is False :
173+ LOGGER .info (f"Parameter validation failed: { param_validation ['errors' ]} " )
174+ raise ValueError (f"Parameter validation failed: { param_validation ['errors' ]} " ) from None
175+ else :
176+ LOGGER .info ("Parameter validation succeeded" )
177+
144178 LOGGER .info ("Getting resource params..." )
145- # TODO(liamschn): what parameters do we need for this solution?
146- # event["ResourceProperties"]["CONTROL_TOWER"]
147179 repo .REPO_ZIP_URL = event ["ResourceProperties" ]["SRA_REPO_ZIP_URL" ]
148180 repo .REPO_BRANCH = repo .REPO_ZIP_URL .split ("." )[1 ].split ("/" )[len (repo .REPO_ZIP_URL .split ("." )[1 ].split ("/" )) - 1 ]
149181 repo .SOLUTIONS_DIR = f"/tmp/aws-security-reference-architecture-examples-{ repo .REPO_BRANCH } /aws_sra_examples/solutions"
@@ -182,12 +214,6 @@ def get_resource_parameters(event):
182214 else :
183215 LOGGER .info ("Error retrieving SRA staging bucket ssm parameter. Is the SRA common prerequisites solution deployed?" )
184216 raise ValueError ("Error retrieving SRA staging bucket ssm parameter. Is the SRA common prerequisites solution deployed?" ) from None
185- # TODO(liamschn): remove the RULE_REGIONS_ACCOUNTS parameter after confirming it is no longer used.
186- # if "RULE_REGIONS_ACCOUNTS" in event["ResourceProperties"]:
187- # RULE_REGIONS_ACCOUNTS = json.loads(event["ResourceProperties"]["RULE_REGIONS_ACCOUNTS"].replace("'", '"'))
188- # TODO(liamschn): remove the BEDROCK_MODEL_EVAL_BUCKET parameter after confirming it is no longer used.
189- # if "BEDROCK_MODEL_EVAL_BUCKET" in event["ResourceProperties"]:
190- # BEDROCK_MODEL_EVAL_BUCKET = event["ResourceProperties"]["BEDROCK_MODEL_EVAL_BUCKET"]
191217
192218 if event ["ResourceProperties" ]["SRA_ALARM_EMAIL" ] != "" :
193219 SRA_ALARM_EMAIL = event ["ResourceProperties" ]["SRA_ALARM_EMAIL" ]
@@ -203,61 +229,28 @@ def get_resource_parameters(event):
203229 CFN_RESPONSE_DATA ["dry_run" ] = DRY_RUN
204230
205231
206- def parameter_pattern_validator ( parameter_name : str , parameter_value : str , pattern : str , is_optional : bool = False ) -> dict :
207- """Validate CloudFormation Custom Resource Properties and/or Lambda Function Environment Variables .
232+ def validate_parameters ( parameters : Dict [ str , str ], rules : Dict [ str , str ] ) -> Dict [ str , object ] :
233+ """Validates each parameter against its corresponding regular expression .
208234
209235 Args:
210- parameter_name: CloudFormation custom resource parameter name and/or Lambda function environment variable name
211- parameter_value: CloudFormation custom resource parameter value and/or Lambda function environment variable value
212- pattern: REGEX pattern to validate against.
213- is_optional: Allow empty or missing value when True
214-
215- Raises:
216- ValueError: Parameter has a value of empty string.
217- ValueError: Parameter is missing
218- ValueError: Parameter does not follow the allowed pattern
236+ parameters (Dict[str, str]): Dictionary of parameters to validate
237+ rules (Dict[str, str]): Dictionary of parameter names and regex patterns
219238
220239 Returns:
221- Validated Parameter
240+ Dict[str, object]: Dictionary with 'success' key (bool) and 'errors' key (list of error messages)
222241 """
223- if parameter_value == "" and not is_optional :
224- raise ValueError (f"({ parameter_name } ) parameter has a value of empty string." )
225- elif not parameter_value and not is_optional :
226- raise ValueError (f"({ parameter_name } ) parameter is missing." )
227- elif not re .match (pattern , str (parameter_value )):
228- raise ValueError (f"({ parameter_name } ) parameter with value of ({ parameter_value } )" + f" does not follow the allowed pattern: { pattern } ." )
229- return {parameter_name : parameter_value }
230-
231- def parameter_pattern_lookup ():
232- # define a dictionary of patterns for all the ResourceProperties in the sra-bedrock-org-main.yaml file for this lambda function
233- # the key is the ResourceProperties name and the value is the REGEX pattern to validate against
234- # the pattern is the same as the AllowedValues in the sra-bedrock-org-main.yaml file for this lambda function
235- patterns = {
236- "SRA_REPO_ZIP_URL" : r'^https://.*\.zip$' ,
237- "DRY_RUN" : r'^true|false$' ,
238- "EXECUTION_ROLE_NAME" : r'^sra-execution$' ,
239- "LOG_GROUP_DEPLOY" : r'^true|false$' ,
240- "LOG_GROUP_RETENTION" : r'^(1|3|5|7|14|30|60|90|120|150|180|365|400|545|731|1096|1827|2192|2557|2922|3288|3653)$' ,
241- "LOG_LEVEL" : r'^(DEBUG|INFO|WARNING|ERROR|CRITICAL)$' ,
242- "SOLUTION_NAME" : r'^sra-bedrock-org$' ,
243- "SOLUTION_VERSION" : r'^[0-9]+\.[0-9]+\.[0-9]+$' ,
244- "SRA_ALARM_EMAIL" : r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$' ,
245- "SRA-BEDROCK-ACCOUNTS" : r'^\[((?:"[0-9]+"(?:\s*,\s*)?)*)\]$' ,
246- "SRA-BEDROCK-REGIONS" : r'^\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\]$' ,
247- "SRA-BEDROCK-CHECK-EVAL-JOB-BUCKET" : r'^\{"deploy"\s*:\s*"(true|false)",\s*"accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\],\s*"input_params"\s*:\s*(\{\s*(?:"BucketName"\s*:\s*"([a-zA-Z0-9-]*)"\s*)?})\}$' ,
248- "SRA-BEDROCK-CHECK-IAM-USER-ACCESS" : r'^\{"deploy"\s*:\s*"(true|false)",\s*"accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\],\s*"input_params"\s*:\s*(\{\s*(?:"BucketName"\s*:\s*"([a-zA-Z0-9-]*)"\s*)?})\}$' ,
249- "SRA-BEDROCK-CHECK-GUARDRAILS" : r'^\{"deploy"\s*:\s*"(true|false)",\s*"accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\],\s*"input_params"\s*:\s*\{(\s*"content_filters"\s*:\s*"(true|false)")?(\s*,\s*"denied_topics"\s*:\s*"(true|false)")?(\s*,\s*"word_filters"\s*:\s*"(true|false)")?(\s*,\s*"sensitive_info_filters"\s*:\s*"(true|false)")?(\s*,\s*"contextual_grounding"\s*:\s*"(true|false)")?\s*\}\}$' ,
250- "SRA-BEDROCK-CHECK-VPC-ENDPOINTS" : r'^\{"deploy"\s*:\s*"(true|false)",\s*"accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\],\s*"input_params"\s*:\s*\{(\s*"check_bedrock"\s*:\s*"(true|false)")?(\s*,\s*"check_bedrock_agent"\s*:\s*"(true|false)")?(\s*,\s*"check_bedrock_agent_runtime"\s*:\s*"(true|false)")?(\s*,\s*"check_bedrock_runtime"\s*:\s*"(true|false)")?\s*\}\}$' ,
251- "SRA-BEDROCK-CHECK-INVOCATION-LOG-CLOUDWATCH" : r'^\{"deploy"\s*:\s*"(true|false)",\s*"accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\],\s*"input_params"\s*:\s*\{(\s*"check_retention"\s*:\s*"(true|false)")?(\s*,\s*"check_encryption"\s*:\s*"(true|false)")?\}\}$' ,
252- "SRA-BEDROCK-CHECK-INVOCATION-LOG-S3" : r'^\{"deploy"\s*:\s*"(true|false)",\s*"accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\],\s*"input_params"\s*:\s*\{(\s*"check_retention"\s*:\s*"(true|false)")?(\s*,\s*"check_encryption"\s*:\s*"(true|false)")?(\s*,\s*"check_access_logging"\s*:\s*"(true|false)")?(\s*,\s*"check_object_locking"\s*:\s*"(true|false)")?(\s*,\s*"check_versioning"\s*:\s*"(true|false)")?\s*\}\}$' ,
253- "SRA-BEDROCK-CHECK-CLOUDWATCH-ENDPOINTS" : r'^\{"deploy"\s*:\s*"(true|false)",\s*"accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\],\s*"input_params"\s*:\s*(\{\})\}$' ,
254- "SRA-BEDROCK-CHECK-S3-ENDPOINTS" : r'^\{"deploy"\s*:\s*"(true|false)",\s*"accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\],\s*"input_params"\s*:\s*(\{\})\}$' ,
255- "SRA-BEDROCK-CHECK-GUARDRAIL-ENCRYPTION" : r'^\{"deploy"\s*:\s*"(true|false)",\s*"accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\],\s*"input_params"\s*:\s*(\{\})\}$' ,
256- "SRA-BEDROCK-FILTER-SERVICE-CHANGES" : r'^\{"deploy"\s*:\s*"(true|false)",\s*"accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\],\s*"filter_params"\s*:\s*\{"log_group_name"\s*:\s*"[^"\s]+"\}\}$' ,
257- "SRA-BEDROCK-FILTER-BUCKET-CHANGES" : r'^\{"deploy"\s*:\s*"(true|false)",\s*"accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\],\s*"filter_params"\s*:\s*\{"log_group_name"\s*:\s*"[^"\s]+",\s*"bucket_names"\s*:\s*\[((?:"[^"\s]+"(?:\s*,\s*)?)+)\]\}\}$' ,
258- "SRA-BEDROCK-FILTER-PROMPT-INJECTION" : r'^\{"deploy"\s*:\s*"(true|false)",\s*"accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\],\s*"filter_params"\s*:\s*\{"log_group_name"\s*:\s*"[^"\s]+",\s*"input_path"\s*:\s*"[^"\s]+"\}\}$' ,
259- "SRA-BEDROCK-FILTER-SENSITIVE-INFO" : r'^\{"deploy"\s*:\s*"(true|false)",\s*"accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\],\s*"filter_params"\s*:\s*\{"log_group_name"\s*:\s*"[^"\s]+",\s*"input_path"\s*:\s*"[^"\s]+"\}\}$' ,
260- "SRA-BEDROCK-CENTRAL-OBSERVABILITY" : r'^\{"deploy"\s*:\s*"(true|false)",\s*"bedrock_accounts"\s*:\s*\[((?:"[0-9]+"(?:\s*,\s*)?)*)\],\s*"regions"\s*:\s*\[((?:"[a-z0-9-]+"(?:\s*,\s*)?)*)\]\}$' ,
242+ errors : List [str ] = []
243+
244+ for param , regex in rules .items ():
245+ value = parameters .get (param )
246+ if value is None :
247+ errors .append (f"Parameter '{ param } ' is missing." )
248+ elif not re .match (regex , value ):
249+ errors .append (f"Parameter '{ param } ' with value '{ value } ' does not match the expected pattern '{ regex } '." )
250+
251+ return {
252+ "success" : len (errors ) == 0 ,
253+ "errors" : errors
261254 }
262255
263256
0 commit comments