@@ -211,8 +211,52 @@ def _list_contains_function():
211211
212212 retry (_list_contains_function , retries = 5 , sleep = 2 )
213213
214- # Invoke is classified as a read operation for proxy purposes
215- # (it executes the function but doesn't modify it)
214+ # Invoke has side-effects and is NOT a read operation - should be blocked in read_only mode
215+ with pytest .raises (ClientError ) as ctx :
216+ lambda_client .invoke (
217+ FunctionName = function_name ,
218+ Payload = json .dumps ({"key" : "value" }),
219+ )
220+ assert ctx .value .response ["Error" ]["Code" ] == "ResourceNotFoundException"
221+
222+ # UpdateFunctionConfiguration is a write operation - should be blocked
223+ with pytest .raises (ClientError ) as ctx :
224+ lambda_client .update_function_configuration (
225+ FunctionName = function_name ,
226+ Description = "updated via proxy - should not work" ,
227+ )
228+ assert ctx .value .response ["Error" ]["Code" ] == "ResourceNotFoundException"
229+
230+
231+ def test_lambda_invoke_mode (start_aws_proxy , cleanups , lambda_execution_role ):
232+ """Test Lambda proxy with read_only + invoke mode: reads and invocations proxied, writes blocked."""
233+ function_name = f"test-fn-inv-{ short_uid ()} "
234+
235+ # start proxy with read_only + invoke flags
236+ config = ProxyConfig (
237+ services = {"lambda" : {"resources" : ".*" , "read_only" : True , "execute" : True }}
238+ )
239+ start_aws_proxy (config )
240+
241+ # create clients
242+ region_name = "us-east-1"
243+ lambda_client = connect_to (region_name = region_name ).lambda_
244+ lambda_client_aws = boto3 .client ("lambda" , region_name = region_name )
245+
246+ # create function in real AWS (direct, not through proxy)
247+ _create_lambda_function (
248+ lambda_client_aws , function_name , lambda_execution_role , cleanups
249+ )
250+
251+ # read operations should be proxied
252+ fn_local = lambda_client .get_function (FunctionName = function_name )
253+ fn_aws = lambda_client_aws .get_function (FunctionName = function_name )
254+ assert (
255+ fn_local ["Configuration" ]["FunctionArn" ]
256+ == fn_aws ["Configuration" ]["FunctionArn" ]
257+ )
258+
259+ # Invoke should be proxied when execute: True is set alongside read_only
216260 response = lambda_client .invoke (
217261 FunctionName = function_name ,
218262 Payload = json .dumps ({"key" : "value" }),
@@ -222,7 +266,7 @@ def _list_contains_function():
222266 body = json .loads (payload ["body" ])
223267 assert body ["message" ] == "hello"
224268
225- # UpdateFunctionConfiguration is a write operation - should be blocked
269+ # UpdateFunctionConfiguration is a write operation - should still be blocked
226270 with pytest .raises (ClientError ) as ctx :
227271 lambda_client .update_function_configuration (
228272 FunctionName = function_name ,
0 commit comments