diff --git a/kong/llm/drivers/bedrock.lua b/kong/llm/drivers/bedrock.lua index 77a532c67fb..1226b5590f8 100644 --- a/kong/llm/drivers/bedrock.lua +++ b/kong/llm/drivers/bedrock.lua @@ -459,13 +459,21 @@ function _M.subrequest(body, conf, http_opts, return_res_table, identity_interfa return nil, nil, "body must be table or string" end + local model_name_processed = conf.model.name + + local is_arn = conf.model.name:find("^arn:aws:bedrock") + if is_arn then + -- if the model name is an ARN, we need to escape it for the URL + model_name_processed = ngx.escape_uri(conf.model.name) + end + -- may be overridden local f_url = conf.model.options and conf.model.options.upstream_url if not f_url then -- upstream_url override is not set local uri = fmt(ai_shared.upstream_url_format[DRIVER_NAME], identity_interface.interface.config.region) local path = fmt( ai_shared.operation_map[DRIVER_NAME][conf.route_type].path, - conf.model.name, + model_name_processed, "converse") f_url = uri ..path @@ -487,6 +495,14 @@ function _M.subrequest(body, conf, http_opts, return_res_table, identity_interfa body = body_string, } + if is_arn then + -- sigv4 requires the canonical URI to be escaped twice + r.canonicalURI = fmt( + ai_shared.operation_map[DRIVER_NAME][conf.route_type].path, + ngx.escape_uri(model_name_processed), + "converse") + end + local signature, err = signer(identity_interface.interface.config, r) if not signature then return nil, "failed to sign AWS request: " .. (err or "NONE") @@ -550,11 +566,20 @@ function _M.configure_request(conf, aws_sdk) or "converse" local f_url = conf.model.options and conf.model.options.upstream_url + + local model_name_processed = conf.model.name + + local is_arn = conf.model.name:find("^arn:aws:bedrock") + if is_arn then + -- if the model name is an ARN, we need to escape it for the URL + model_name_processed = ngx.escape_uri(conf.model.name) + end + if not f_url then -- upstream_url override is not set local uri = fmt(ai_shared.upstream_url_format[DRIVER_NAME], aws_sdk.config.region) local path = fmt( ai_shared.operation_map[DRIVER_NAME][conf.route_type].path, - conf.model.name, + model_name_processed, operation) f_url = uri ..path @@ -589,6 +614,14 @@ function _M.configure_request(conf, aws_sdk) body = kong.request.get_raw_body() } + if is_arn then + -- sigv4 requires the canonical URI to be escaped twice + r.canonicalURI = fmt( + ai_shared.operation_map[DRIVER_NAME][conf.route_type].path, + ngx.escape_uri(model_name_processed), + operation) + end + local signature, err = signer(aws_sdk.config, r) if not signature then return nil, "failed to sign AWS request: " .. (err or "NONE")