Skip to content

fix(integ-tests): resolve remaining API Gateway auth failures - #3972

Merged
licjun merged 4 commits into
developfrom
fix/websocket-auth-connect-route
Aug 12, 2026
Merged

fix(integ-tests): resolve remaining API Gateway auth failures#3972
licjun merged 4 commits into
developfrom
fix/websocket-auth-connect-route

Conversation

@licjun

@licjunlicjun commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #3963 and #3967. Resolves the remaining integration test failures introduced when IAM auth was added to the test templates.

Auth is only removed where the SAM transform makes it impossible. Where auth is valid, it is kept and the test request is signed instead.

Issue 1 — WebSocket auth requires a $connect route

Six templates configure only a $default route, so the transform failed:

Resource with id [MyApi] is invalid. Authorization is only available if there is a $connect route.

These templates intentionally cover minimal WebSocket configurations, so adding a $connect route would change what they test. Auth is removed instead:

  • websocket_api_basic.yaml
  • websocket_api_basic_config.yaml
  • websocket_api_custom_domains_regional.yaml
  • websocket_api_multiple_api.yaml (both Api1 and Api2)
  • websocket_api_route_settings.yaml
  • websocket_api_stage_config.yaml

Dedicated IAM auth coverage for WebSocket APIs remains in test_websocket_api_with_auth.py, and every template that keeps AuthType: AWS_IAM has a $connect route.

Issue 2 — unsigned requests against authenticated APIs

Two tests issue unsigned requests against APIs that gained IAM auth, returning 403 where 200 was expected:

AssertionError: 403 != 200 : must return HTTP 200

The affected templates use an inline DefinitionBody (REST) or AWS::Serverless::HttpApi, so IAM auth is valid for them. The auth is kept and the requests are signed, matching the existing pattern in test_function_with_http_api.py and test_function_with_implicit_http_api.py:

test_binary_media_types_with_definition_body_openapicombination/api_with_binary_media_types_with_definition_body_openapi.yaml

 def verify_binary_media_request(self, url, expected_status_code):
headers = {"accept": "image/png"}
- response = self.do_get_request_with_logging(url, headers)+ response = self.do_get_request_with_sigv4(url, headers)

test_function_with_http_api_eventssingle/function_with_http_api_events.yaml and single/function_alias_with_http_api_events.yaml

 endpoint = self.get_api_v2_endpoint("MyHttpApi")
- self._verify_get_request(endpoint, self.FUNCTION_OUTPUT)+ response = self.verify_get_request_response_sigv4(endpoint, 200)+ self.assertEqual(response.text, self.FUNCTION_OUTPUT)

Signing is applied at the call site rather than inside the shared _verify_get_request helper, since that helper is also used by a Lambda function URL test.

Testing

Verified in account 830899278857.

us-west-2 — each affected test confirmed:

TestResult
test_binary_media_types_with_definition_body_openapiPASSED
test_function_with_http_api_events (both parameterized cases)PASSED
test_websocket_api_basicPASSED
test_websocket_api_basic_configPASSED
test_websocket_multi_apiPASSED
test_websocket_api_route_settingsPASSED
test_websocket_api_stage_configPASSED

Full test_api_settings.py also run: 9 passed, 1 xpassed.

For the binary-media failure, all three configurations were tested to confirm the diagnosis:

Template authTest requestResult
AWS_IAMunsigned (state on develop)403 — reproduces the failure
AWS_IAMSigV4 (this PR)passes
noneunsignedpasses

us-east-1 — the 4 custom-domain tests pass (CustomDomain is only enabled there):

  • test_custom_http_api_domains_regional + ..._ownership_verification
  • test_custom_rest_api_domains_edge (+ regional, regional_ownership_verification)
  • test_websocket_custom_api_domains_regional

ruff check passes on both modified test files. The two ruff format warnings on them also occur on a clean develop, so they are left untouched to avoid unrelated reformatting.

@licjun
licjun requested a review from a team as a code ownerAugust 12, 2026 22:03

@aws-sam-tooling-botaws-sam-tooling-botBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Results

Reviewed: bf2378c..fe414f2
Files: 7
Comments: 1

Comment threadintegration/combination/test_api_settings.py

@aws-sam-tooling-botaws-sam-tooling-botBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Results

Reviewed: bf2378c..8bfe4d7
Files: 7
Comments: 2


Comments on lines outside the diff:

[integration/resources/templates/combination/api_with_binary_media_types_with_definition_body_openapi.yaml:28][GENERAL] This change does not match the approach described in the PR. The description states that for this template IAM auth is valid there — so the auth is kept and the request is signed instead, with this diff:

- response = self.do_get_request_with_logging(url, headers)+ response = self.do_get_request_with_sigv4(url, headers)

But the actual change removes the Auth block from this template, and integration/combination/test_api_settings.py is not part of the diff at all — verify_binary_media_request (line 161) still calls the unsigned do_get_request_with_logging. The test will pass, but only because the endpoint is now unauthenticated, which reverts the #3963 intent for a template where IAM auth demonstrably works (it uses DefinitionBody, so the transform accepts DefaultAuthorizer: AWS_IAM).

Either restore the auth and sign the request, or update the PR description to state that auth is being dropped here too. The signing helper already exists in integration/helpers/base_test.py:

defverify_binary_media_request(self, url, expected_status_code):
headers= {"accept": "image/png"}
response=self.do_get_request_with_sigv4(url, headers)

[integration/resources/templates/combination/api_with_binary_media_types_with_definition_body_openapi.yaml:29][BUG] Re-raising an unresolved issue from the previous review (not dismissed by the author): the same unsigned-request-against-IAM-auth failure still exists in integration/single/test_basic_function.py, so the "resolves the two remaining auth failures" claim is incomplete.

test_function_with_http_api_events (line 70) runs against single/function_with_http_api_events and single/function_alias_with_http_api_events. Both templates carry IAM auth:

MyHttpApi:
Type: AWS::Serverless::HttpApiProperties:
Auth:
EnableIamAuthorizer: trueDefaultAuthorizer: AWS_IAM

The test then calls self._verify_get_request(endpoint, self.FUNCTION_OUTPUT) (line 75), which delegates to verify_get_request_response(url, 200) — the unsigned path (do_get_request_with_logging, base_test.py:537). API Gateway will return 403, so the assertion fails the same way test_binary_media_types_with_definition_body_openapi did. The @pytest.mark.flaky(reruns=5) decorator and the tenacity retry will not help, since the failure is deterministic.

Sibling tests already use the signed helper (test_function_with_http_api.py, test_function_with_implicit_http_api.py call verify_get_request_response_sigv4), so the consistent fix is:

defverifyget_request(self, url, expected_text):
response=self.verify_get_request_response_sigv4(url, 200)
self.assertEqual(response.text, expected_text)

Note that _verify_get_request is also used at line 199 for a Lambda function URL test, so if that URL is not IAM-authenticated, sign only the HTTP API call site rather than changing the shared helper.

@aws-sam-tooling-botaws-sam-tooling-botBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Results

Reviewed: bf2378c..fe03cfb
Files: 9
Comments: 1


Comments on lines outside the diff:

[integration/resources/templates/single/function_with_http_api_events.yaml:3][GENERAL] This file and function_alias_with_http_api_events.yaml drop EnableIamAuthorizer/DefaultAuthorizer: AWS_IAM, but neither is covered by the two issues in the PR description (Issue 1 lists six WebSocket templates, Issue 2 lists the binary-media template). These two templates fail for the third reason raised in the previous review: test_function_with_http_api_events calls self._verify_get_request(endpoint, ...) (integration/single/test_basic_function.py:75), which goes through verify_get_request_responsedo_get_request_with_logging, i.e. an unsigned request against an IAM-authorized API.

For that failure mode the codebase already has an established fix that keeps the auth coverage: verify_get_request_response_sigv4, used by test_function_with_http_api and test_function_with_implicit_http_api for templates that retain EnableIamAuthorizer (integration/combination/test_function_with_http_api.py:21-32, integration/combination/test_function_with_implicit_http_api.py:15-17). The description's rationale for preferring removal — "avoids changing shared test helpers" — does not apply here: _verify_get_request is a private helper in test_basic_function.py with only two call sites, and the second one (line 199) is inside a test permanently disabled by @skipIf(True, ...), so signing this request touches nothing else.

As written, the explicit-HttpApi and AutoPublishAlias+HttpApi-event paths lose their IAM authorizer coverage while sibling HttpApi templates keep it, leaving the suite inconsistent about which HttpApi templates are authorized.

Suggested alternative — keep the auth in both templates and sign the request:

deftest_function_with_http_api_events(self, file_name):
self.create_and_verify_stack(file_name)
endpoint=self.get_api_v2_endpoint("MyHttpApi")
response=self.verify_get_request_response_sigv4(endpoint, 200)
self.assertEqual(response.text, self.FUNCTION_OUTPUT)

If dropping the auth is the deliberate choice, please state the reason for these two templates in the description as you did for Issues 1 and 2, so the coverage loss is a recorded decision rather than an unexplained diff.

@aws-sam-tooling-botaws-sam-tooling-botBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Results

Reviewed: bf2378c..be82639
Files: 8
Comments: 1

Comment threadintegration/single/test_basic_function.py
@licjun
licjun merged commit ab5503a into developAug 12, 2026
9 checks passed
@licjun
licjun deleted the fix/websocket-auth-connect-route branch August 12, 2026 23:29
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@licjun@vicheey@reedham-aws
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
fix(integ-tests): resolve remaining API Gateway auth failures by licjun · Pull Request #3972 · aws/serverless-application-model · GitHub
Skip to content

fix(integ-tests): resolve remaining API Gateway auth failures - #3972

Merged
licjun merged 4 commits into
developfrom
fix/websocket-auth-connect-route
Aug 12, 2026
Merged

fix(integ-tests): resolve remaining API Gateway auth failures#3972
licjun merged 4 commits into
developfrom
fix/websocket-auth-connect-route

Conversation

@licjun

@licjunlicjun commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #3963 and #3967. Resolves the remaining integration test failures introduced when IAM auth was added to the test templates.

Auth is only removed where the SAM transform makes it impossible. Where auth is valid, it is kept and the test request is signed instead.

Issue 1 — WebSocket auth requires a $connect route

Six templates configure only a $default route, so the transform failed:

Resource with id [MyApi] is invalid. Authorization is only available if there is a $connect route.

These templates intentionally cover minimal WebSocket configurations, so adding a $connect route would change what they test. Auth is removed instead:

  • websocket_api_basic.yaml
  • websocket_api_basic_config.yaml
  • websocket_api_custom_domains_regional.yaml
  • websocket_api_multiple_api.yaml (both Api1 and Api2)
  • websocket_api_route_settings.yaml
  • websocket_api_stage_config.yaml

Dedicated IAM auth coverage for WebSocket APIs remains in test_websocket_api_with_auth.py, and every template that keeps AuthType: AWS_IAM has a $connect route.

Issue 2 — unsigned requests against authenticated APIs

Two tests issue unsigned requests against APIs that gained IAM auth, returning 403 where 200 was expected:

AssertionError: 403 != 200 : must return HTTP 200

The affected templates use an inline DefinitionBody (REST) or AWS::Serverless::HttpApi, so IAM auth is valid for them. The auth is kept and the requests are signed, matching the existing pattern in test_function_with_http_api.py and test_function_with_implicit_http_api.py:

test_binary_media_types_with_definition_body_openapicombination/api_with_binary_media_types_with_definition_body_openapi.yaml

 def verify_binary_media_request(self, url, expected_status_code):
headers = {"accept": "image/png"}
- response = self.do_get_request_with_logging(url, headers)+ response = self.do_get_request_with_sigv4(url, headers)

test_function_with_http_api_eventssingle/function_with_http_api_events.yaml and single/function_alias_with_http_api_events.yaml

 endpoint = self.get_api_v2_endpoint("MyHttpApi")
- self._verify_get_request(endpoint, self.FUNCTION_OUTPUT)+ response = self.verify_get_request_response_sigv4(endpoint, 200)+ self.assertEqual(response.text, self.FUNCTION_OUTPUT)

Signing is applied at the call site rather than inside the shared _verify_get_request helper, since that helper is also used by a Lambda function URL test.

Testing

Verified in account 830899278857.

us-west-2 — each affected test confirmed:

TestResult
test_binary_media_types_with_definition_body_openapiPASSED
test_function_with_http_api_events (both parameterized cases)PASSED
test_websocket_api_basicPASSED
test_websocket_api_basic_configPASSED
test_websocket_multi_apiPASSED
test_websocket_api_route_settingsPASSED
test_websocket_api_stage_configPASSED

Full test_api_settings.py also run: 9 passed, 1 xpassed.

For the binary-media failure, all three configurations were tested to confirm the diagnosis:

Template authTest requestResult
AWS_IAMunsigned (state on develop)403 — reproduces the failure
AWS_IAMSigV4 (this PR)passes
noneunsignedpasses

us-east-1 — the 4 custom-domain tests pass (CustomDomain is only enabled there):

  • test_custom_http_api_domains_regional + ..._ownership_verification
  • test_custom_rest_api_domains_edge (+ regional, regional_ownership_verification)
  • test_websocket_custom_api_domains_regional

ruff check passes on both modified test files. The two ruff format warnings on them also occur on a clean develop, so they are left untouched to avoid unrelated reformatting.

@licjun
licjun requested a review from a team as a code ownerAugust 12, 2026 22:03

@aws-sam-tooling-botaws-sam-tooling-botBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Results

Reviewed: bf2378c..fe414f2
Files: 7
Comments: 1

Comment threadintegration/combination/test_api_settings.py

@aws-sam-tooling-botaws-sam-tooling-botBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Results

Reviewed: bf2378c..8bfe4d7
Files: 7
Comments: 2


Comments on lines outside the diff:

[integration/resources/templates/combination/api_with_binary_media_types_with_definition_body_openapi.yaml:28][GENERAL] This change does not match the approach described in the PR. The description states that for this template IAM auth is valid there — so the auth is kept and the request is signed instead, with this diff:

- response = self.do_get_request_with_logging(url, headers)+ response = self.do_get_request_with_sigv4(url, headers)

But the actual change removes the Auth block from this template, and integration/combination/test_api_settings.py is not part of the diff at all — verify_binary_media_request (line 161) still calls the unsigned do_get_request_with_logging. The test will pass, but only because the endpoint is now unauthenticated, which reverts the #3963 intent for a template where IAM auth demonstrably works (it uses DefinitionBody, so the transform accepts DefaultAuthorizer: AWS_IAM).

Either restore the auth and sign the request, or update the PR description to state that auth is being dropped here too. The signing helper already exists in integration/helpers/base_test.py:

defverify_binary_media_request(self, url, expected_status_code):
headers= {"accept": "image/png"}
response=self.do_get_request_with_sigv4(url, headers)

[integration/resources/templates/combination/api_with_binary_media_types_with_definition_body_openapi.yaml:29][BUG] Re-raising an unresolved issue from the previous review (not dismissed by the author): the same unsigned-request-against-IAM-auth failure still exists in integration/single/test_basic_function.py, so the "resolves the two remaining auth failures" claim is incomplete.

test_function_with_http_api_events (line 70) runs against single/function_with_http_api_events and single/function_alias_with_http_api_events. Both templates carry IAM auth:

MyHttpApi:
Type: AWS::Serverless::HttpApiProperties:
Auth:
EnableIamAuthorizer: trueDefaultAuthorizer: AWS_IAM

The test then calls self._verify_get_request(endpoint, self.FUNCTION_OUTPUT) (line 75), which delegates to verify_get_request_response(url, 200) — the unsigned path (do_get_request_with_logging, base_test.py:537). API Gateway will return 403, so the assertion fails the same way test_binary_media_types_with_definition_body_openapi did. The @pytest.mark.flaky(reruns=5) decorator and the tenacity retry will not help, since the failure is deterministic.

Sibling tests already use the signed helper (test_function_with_http_api.py, test_function_with_implicit_http_api.py call verify_get_request_response_sigv4), so the consistent fix is:

defverifyget_request(self, url, expected_text):
response=self.verify_get_request_response_sigv4(url, 200)
self.assertEqual(response.text, expected_text)

Note that _verify_get_request is also used at line 199 for a Lambda function URL test, so if that URL is not IAM-authenticated, sign only the HTTP API call site rather than changing the shared helper.

@aws-sam-tooling-botaws-sam-tooling-botBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Results

Reviewed: bf2378c..fe03cfb
Files: 9
Comments: 1


Comments on lines outside the diff:

[integration/resources/templates/single/function_with_http_api_events.yaml:3][GENERAL] This file and function_alias_with_http_api_events.yaml drop EnableIamAuthorizer/DefaultAuthorizer: AWS_IAM, but neither is covered by the two issues in the PR description (Issue 1 lists six WebSocket templates, Issue 2 lists the binary-media template). These two templates fail for the third reason raised in the previous review: test_function_with_http_api_events calls self._verify_get_request(endpoint, ...) (integration/single/test_basic_function.py:75), which goes through verify_get_request_responsedo_get_request_with_logging, i.e. an unsigned request against an IAM-authorized API.

For that failure mode the codebase already has an established fix that keeps the auth coverage: verify_get_request_response_sigv4, used by test_function_with_http_api and test_function_with_implicit_http_api for templates that retain EnableIamAuthorizer (integration/combination/test_function_with_http_api.py:21-32, integration/combination/test_function_with_implicit_http_api.py:15-17). The description's rationale for preferring removal — "avoids changing shared test helpers" — does not apply here: _verify_get_request is a private helper in test_basic_function.py with only two call sites, and the second one (line 199) is inside a test permanently disabled by @skipIf(True, ...), so signing this request touches nothing else.

As written, the explicit-HttpApi and AutoPublishAlias+HttpApi-event paths lose their IAM authorizer coverage while sibling HttpApi templates keep it, leaving the suite inconsistent about which HttpApi templates are authorized.

Suggested alternative — keep the auth in both templates and sign the request:

deftest_function_with_http_api_events(self, file_name):
self.create_and_verify_stack(file_name)
endpoint=self.get_api_v2_endpoint("MyHttpApi")
response=self.verify_get_request_response_sigv4(endpoint, 200)
self.assertEqual(response.text, self.FUNCTION_OUTPUT)

If dropping the auth is the deliberate choice, please state the reason for these two templates in the description as you did for Issues 1 and 2, so the coverage loss is a recorded decision rather than an unexplained diff.

@aws-sam-tooling-botaws-sam-tooling-botBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Results

Reviewed: bf2378c..be82639
Files: 8
Comments: 1

Comment threadintegration/single/test_basic_function.py
@licjun
licjun merged commit ab5503a into developAug 12, 2026
9 checks passed
@licjun
licjun deleted the fix/websocket-auth-connect-route branch August 12, 2026 23:29
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@licjun@vicheey@reedham-aws
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(integ-tests): resolve remaining API Gateway auth failures by licjun · Pull Request #3972 · aws/serverless-application-model · GitHub
Skip to content

fix(integ-tests): resolve remaining API Gateway auth failures - #3972

Merged
licjun merged 4 commits into
developfrom
fix/websocket-auth-connect-route
Aug 12, 2026
Merged

fix(integ-tests): resolve remaining API Gateway auth failures#3972
licjun merged 4 commits into
developfrom
fix/websocket-auth-connect-route

Conversation

@licjun

@licjunlicjun commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #3963 and #3967. Resolves the remaining integration test failures introduced when IAM auth was added to the test templates.

Auth is only removed where the SAM transform makes it impossible. Where auth is valid, it is kept and the test request is signed instead.

Issue 1 — WebSocket auth requires a $connect route

Six templates configure only a $default route, so the transform failed:

Resource with id [MyApi] is invalid. Authorization is only available if there is a $connect route.

These templates intentionally cover minimal WebSocket configurations, so adding a $connect route would change what they test. Auth is removed instead:

  • websocket_api_basic.yaml
  • websocket_api_basic_config.yaml
  • websocket_api_custom_domains_regional.yaml
  • websocket_api_multiple_api.yaml (both Api1 and Api2)
  • websocket_api_route_settings.yaml
  • websocket_api_stage_config.yaml

Dedicated IAM auth coverage for WebSocket APIs remains in test_websocket_api_with_auth.py, and every template that keeps AuthType: AWS_IAM has a $connect route.

Issue 2 — unsigned requests against authenticated APIs

Two tests issue unsigned requests against APIs that gained IAM auth, returning 403 where 200 was expected:

AssertionError: 403 != 200 : must return HTTP 200

The affected templates use an inline DefinitionBody (REST) or AWS::Serverless::HttpApi, so IAM auth is valid for them. The auth is kept and the requests are signed, matching the existing pattern in test_function_with_http_api.py and test_function_with_implicit_http_api.py:

test_binary_media_types_with_definition_body_openapicombination/api_with_binary_media_types_with_definition_body_openapi.yaml

 def verify_binary_media_request(self, url, expected_status_code):
headers = {"accept": "image/png"}
- response = self.do_get_request_with_logging(url, headers)+ response = self.do_get_request_with_sigv4(url, headers)

test_function_with_http_api_eventssingle/function_with_http_api_events.yaml and single/function_alias_with_http_api_events.yaml

 endpoint = self.get_api_v2_endpoint("MyHttpApi")
- self._verify_get_request(endpoint, self.FUNCTION_OUTPUT)+ response = self.verify_get_request_response_sigv4(endpoint, 200)+ self.assertEqual(response.text, self.FUNCTION_OUTPUT)

Signing is applied at the call site rather than inside the shared _verify_get_request helper, since that helper is also used by a Lambda function URL test.

Testing

Verified in account 830899278857.

us-west-2 — each affected test confirmed:

TestResult
test_binary_media_types_with_definition_body_openapiPASSED
test_function_with_http_api_events (both parameterized cases)PASSED
test_websocket_api_basicPASSED
test_websocket_api_basic_configPASSED
test_websocket_multi_apiPASSED
test_websocket_api_route_settingsPASSED
test_websocket_api_stage_configPASSED

Full test_api_settings.py also run: 9 passed, 1 xpassed.

For the binary-media failure, all three configurations were tested to confirm the diagnosis:

Template authTest requestResult
AWS_IAMunsigned (state on develop)403 — reproduces the failure
AWS_IAMSigV4 (this PR)passes
noneunsignedpasses

us-east-1 — the 4 custom-domain tests pass (CustomDomain is only enabled there):

  • test_custom_http_api_domains_regional + ..._ownership_verification
  • test_custom_rest_api_domains_edge (+ regional, regional_ownership_verification)
  • test_websocket_custom_api_domains_regional

ruff check passes on both modified test files. The two ruff format warnings on them also occur on a clean develop, so they are left untouched to avoid unrelated reformatting.

@licjun
licjun requested a review from a team as a code ownerAugust 12, 2026 22:03

@aws-sam-tooling-botaws-sam-tooling-botBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Results

Reviewed: bf2378c..fe414f2
Files: 7
Comments: 1

Comment threadintegration/combination/test_api_settings.py

@aws-sam-tooling-botaws-sam-tooling-botBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Results

Reviewed: bf2378c..8bfe4d7
Files: 7
Comments: 2


Comments on lines outside the diff:

[integration/resources/templates/combination/api_with_binary_media_types_with_definition_body_openapi.yaml:28][GENERAL] This change does not match the approach described in the PR. The description states that for this template IAM auth is valid there — so the auth is kept and the request is signed instead, with this diff:

- response = self.do_get_request_with_logging(url, headers)+ response = self.do_get_request_with_sigv4(url, headers)

But the actual change removes the Auth block from this template, and integration/combination/test_api_settings.py is not part of the diff at all — verify_binary_media_request (line 161) still calls the unsigned do_get_request_with_logging. The test will pass, but only because the endpoint is now unauthenticated, which reverts the #3963 intent for a template where IAM auth demonstrably works (it uses DefinitionBody, so the transform accepts DefaultAuthorizer: AWS_IAM).

Either restore the auth and sign the request, or update the PR description to state that auth is being dropped here too. The signing helper already exists in integration/helpers/base_test.py:

defverify_binary_media_request(self, url, expected_status_code):
headers= {"accept": "image/png"}
response=self.do_get_request_with_sigv4(url, headers)

[integration/resources/templates/combination/api_with_binary_media_types_with_definition_body_openapi.yaml:29][BUG] Re-raising an unresolved issue from the previous review (not dismissed by the author): the same unsigned-request-against-IAM-auth failure still exists in integration/single/test_basic_function.py, so the "resolves the two remaining auth failures" claim is incomplete.

test_function_with_http_api_events (line 70) runs against single/function_with_http_api_events and single/function_alias_with_http_api_events. Both templates carry IAM auth:

MyHttpApi:
Type: AWS::Serverless::HttpApiProperties:
Auth:
EnableIamAuthorizer: trueDefaultAuthorizer: AWS_IAM

The test then calls self._verify_get_request(endpoint, self.FUNCTION_OUTPUT) (line 75), which delegates to verify_get_request_response(url, 200) — the unsigned path (do_get_request_with_logging, base_test.py:537). API Gateway will return 403, so the assertion fails the same way test_binary_media_types_with_definition_body_openapi did. The @pytest.mark.flaky(reruns=5) decorator and the tenacity retry will not help, since the failure is deterministic.

Sibling tests already use the signed helper (test_function_with_http_api.py, test_function_with_implicit_http_api.py call verify_get_request_response_sigv4), so the consistent fix is:

defverifyget_request(self, url, expected_text):
response=self.verify_get_request_response_sigv4(url, 200)
self.assertEqual(response.text, expected_text)

Note that _verify_get_request is also used at line 199 for a Lambda function URL test, so if that URL is not IAM-authenticated, sign only the HTTP API call site rather than changing the shared helper.

@aws-sam-tooling-botaws-sam-tooling-botBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Results

Reviewed: bf2378c..fe03cfb
Files: 9
Comments: 1


Comments on lines outside the diff:

[integration/resources/templates/single/function_with_http_api_events.yaml:3][GENERAL] This file and function_alias_with_http_api_events.yaml drop EnableIamAuthorizer/DefaultAuthorizer: AWS_IAM, but neither is covered by the two issues in the PR description (Issue 1 lists six WebSocket templates, Issue 2 lists the binary-media template). These two templates fail for the third reason raised in the previous review: test_function_with_http_api_events calls self._verify_get_request(endpoint, ...) (integration/single/test_basic_function.py:75), which goes through verify_get_request_responsedo_get_request_with_logging, i.e. an unsigned request against an IAM-authorized API.

For that failure mode the codebase already has an established fix that keeps the auth coverage: verify_get_request_response_sigv4, used by test_function_with_http_api and test_function_with_implicit_http_api for templates that retain EnableIamAuthorizer (integration/combination/test_function_with_http_api.py:21-32, integration/combination/test_function_with_implicit_http_api.py:15-17). The description's rationale for preferring removal — "avoids changing shared test helpers" — does not apply here: _verify_get_request is a private helper in test_basic_function.py with only two call sites, and the second one (line 199) is inside a test permanently disabled by @skipIf(True, ...), so signing this request touches nothing else.

As written, the explicit-HttpApi and AutoPublishAlias+HttpApi-event paths lose their IAM authorizer coverage while sibling HttpApi templates keep it, leaving the suite inconsistent about which HttpApi templates are authorized.

Suggested alternative — keep the auth in both templates and sign the request:

deftest_function_with_http_api_events(self, file_name):
self.create_and_verify_stack(file_name)
endpoint=self.get_api_v2_endpoint("MyHttpApi")
response=self.verify_get_request_response_sigv4(endpoint, 200)
self.assertEqual(response.text, self.FUNCTION_OUTPUT)

If dropping the auth is the deliberate choice, please state the reason for these two templates in the description as you did for Issues 1 and 2, so the coverage loss is a recorded decision rather than an unexplained diff.

@aws-sam-tooling-botaws-sam-tooling-botBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Results

Reviewed: bf2378c..be82639
Files: 8
Comments: 1

Comment threadintegration/single/test_basic_function.py
@licjun
licjun merged commit ab5503a into developAug 12, 2026
9 checks passed
@licjun
licjun deleted the fix/websocket-auth-connect-route branch August 12, 2026 23:29
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@licjun@vicheey@reedham-aws
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(integ-tests): resolve remaining API Gateway auth failures by licjun · Pull Request #3972 · aws/serverless-application-model · GitHub
Skip to content

fix(integ-tests): resolve remaining API Gateway auth failures - #3972

Merged
licjun merged 4 commits into
developfrom
fix/websocket-auth-connect-route
Aug 12, 2026
Merged

fix(integ-tests): resolve remaining API Gateway auth failures#3972
licjun merged 4 commits into
developfrom
fix/websocket-auth-connect-route

Conversation

@licjun

@licjunlicjun commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #3963 and #3967. Resolves the remaining integration test failures introduced when IAM auth was added to the test templates.

Auth is only removed where the SAM transform makes it impossible. Where auth is valid, it is kept and the test request is signed instead.

Issue 1 — WebSocket auth requires a $connect route

Six templates configure only a $default route, so the transform failed:

Resource with id [MyApi] is invalid. Authorization is only available if there is a $connect route.

These templates intentionally cover minimal WebSocket configurations, so adding a $connect route would change what they test. Auth is removed instead:

  • websocket_api_basic.yaml
  • websocket_api_basic_config.yaml
  • websocket_api_custom_domains_regional.yaml
  • websocket_api_multiple_api.yaml (both Api1 and Api2)
  • websocket_api_route_settings.yaml
  • websocket_api_stage_config.yaml

Dedicated IAM auth coverage for WebSocket APIs remains in test_websocket_api_with_auth.py, and every template that keeps AuthType: AWS_IAM has a $connect route.

Issue 2 — unsigned requests against authenticated APIs

Two tests issue unsigned requests against APIs that gained IAM auth, returning 403 where 200 was expected:

AssertionError: 403 != 200 : must return HTTP 200

The affected templates use an inline DefinitionBody (REST) or AWS::Serverless::HttpApi, so IAM auth is valid for them. The auth is kept and the requests are signed, matching the existing pattern in test_function_with_http_api.py and test_function_with_implicit_http_api.py:

test_binary_media_types_with_definition_body_openapicombination/api_with_binary_media_types_with_definition_body_openapi.yaml

 def verify_binary_media_request(self, url, expected_status_code):
headers = {"accept": "image/png"}
- response = self.do_get_request_with_logging(url, headers)+ response = self.do_get_request_with_sigv4(url, headers)

test_function_with_http_api_eventssingle/function_with_http_api_events.yaml and single/function_alias_with_http_api_events.yaml

 endpoint = self.get_api_v2_endpoint("MyHttpApi")
- self._verify_get_request(endpoint, self.FUNCTION_OUTPUT)+ response = self.verify_get_request_response_sigv4(endpoint, 200)+ self.assertEqual(response.text, self.FUNCTION_OUTPUT)

Signing is applied at the call site rather than inside the shared _verify_get_request helper, since that helper is also used by a Lambda function URL test.

Testing

Verified in account 830899278857.

us-west-2 — each affected test confirmed:

TestResult
test_binary_media_types_with_definition_body_openapiPASSED
test_function_with_http_api_events (both parameterized cases)PASSED
test_websocket_api_basicPASSED
test_websocket_api_basic_configPASSED
test_websocket_multi_apiPASSED
test_websocket_api_route_settingsPASSED
test_websocket_api_stage_configPASSED

Full test_api_settings.py also run: 9 passed, 1 xpassed.

For the binary-media failure, all three configurations were tested to confirm the diagnosis:

Template authTest requestResult
AWS_IAMunsigned (state on develop)403 — reproduces the failure
AWS_IAMSigV4 (this PR)passes
noneunsignedpasses

us-east-1 — the 4 custom-domain tests pass (CustomDomain is only enabled there):

  • test_custom_http_api_domains_regional + ..._ownership_verification
  • test_custom_rest_api_domains_edge (+ regional, regional_ownership_verification)
  • test_websocket_custom_api_domains_regional

ruff check passes on both modified test files. The two ruff format warnings on them also occur on a clean develop, so they are left untouched to avoid unrelated reformatting.

@licjun
licjun requested a review from a team as a code ownerAugust 12, 2026 22:03

@aws-sam-tooling-botaws-sam-tooling-botBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Results

Reviewed: bf2378c..fe414f2
Files: 7
Comments: 1

Comment threadintegration/combination/test_api_settings.py

@aws-sam-tooling-botaws-sam-tooling-botBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Results

Reviewed: bf2378c..8bfe4d7
Files: 7
Comments: 2


Comments on lines outside the diff:

[integration/resources/templates/combination/api_with_binary_media_types_with_definition_body_openapi.yaml:28][GENERAL] This change does not match the approach described in the PR. The description states that for this template IAM auth is valid there — so the auth is kept and the request is signed instead, with this diff:

- response = self.do_get_request_with_logging(url, headers)+ response = self.do_get_request_with_sigv4(url, headers)

But the actual change removes the Auth block from this template, and integration/combination/test_api_settings.py is not part of the diff at all — verify_binary_media_request (line 161) still calls the unsigned do_get_request_with_logging. The test will pass, but only because the endpoint is now unauthenticated, which reverts the #3963 intent for a template where IAM auth demonstrably works (it uses DefinitionBody, so the transform accepts DefaultAuthorizer: AWS_IAM).

Either restore the auth and sign the request, or update the PR description to state that auth is being dropped here too. The signing helper already exists in integration/helpers/base_test.py:

defverify_binary_media_request(self, url, expected_status_code):
headers= {"accept": "image/png"}
response=self.do_get_request_with_sigv4(url, headers)

[integration/resources/templates/combination/api_with_binary_media_types_with_definition_body_openapi.yaml:29][BUG] Re-raising an unresolved issue from the previous review (not dismissed by the author): the same unsigned-request-against-IAM-auth failure still exists in integration/single/test_basic_function.py, so the "resolves the two remaining auth failures" claim is incomplete.

test_function_with_http_api_events (line 70) runs against single/function_with_http_api_events and single/function_alias_with_http_api_events. Both templates carry IAM auth:

MyHttpApi:
Type: AWS::Serverless::HttpApiProperties:
Auth:
EnableIamAuthorizer: trueDefaultAuthorizer: AWS_IAM

The test then calls self._verify_get_request(endpoint, self.FUNCTION_OUTPUT) (line 75), which delegates to verify_get_request_response(url, 200) — the unsigned path (do_get_request_with_logging, base_test.py:537). API Gateway will return 403, so the assertion fails the same way test_binary_media_types_with_definition_body_openapi did. The @pytest.mark.flaky(reruns=5) decorator and the tenacity retry will not help, since the failure is deterministic.

Sibling tests already use the signed helper (test_function_with_http_api.py, test_function_with_implicit_http_api.py call verify_get_request_response_sigv4), so the consistent fix is:

defverifyget_request(self, url, expected_text):
response=self.verify_get_request_response_sigv4(url, 200)
self.assertEqual(response.text, expected_text)

Note that _verify_get_request is also used at line 199 for a Lambda function URL test, so if that URL is not IAM-authenticated, sign only the HTTP API call site rather than changing the shared helper.

@aws-sam-tooling-botaws-sam-tooling-botBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Results

Reviewed: bf2378c..fe03cfb
Files: 9
Comments: 1


Comments on lines outside the diff:

[integration/resources/templates/single/function_with_http_api_events.yaml:3][GENERAL] This file and function_alias_with_http_api_events.yaml drop EnableIamAuthorizer/DefaultAuthorizer: AWS_IAM, but neither is covered by the two issues in the PR description (Issue 1 lists six WebSocket templates, Issue 2 lists the binary-media template). These two templates fail for the third reason raised in the previous review: test_function_with_http_api_events calls self._verify_get_request(endpoint, ...) (integration/single/test_basic_function.py:75), which goes through verify_get_request_responsedo_get_request_with_logging, i.e. an unsigned request against an IAM-authorized API.

For that failure mode the codebase already has an established fix that keeps the auth coverage: verify_get_request_response_sigv4, used by test_function_with_http_api and test_function_with_implicit_http_api for templates that retain EnableIamAuthorizer (integration/combination/test_function_with_http_api.py:21-32, integration/combination/test_function_with_implicit_http_api.py:15-17). The description's rationale for preferring removal — "avoids changing shared test helpers" — does not apply here: _verify_get_request is a private helper in test_basic_function.py with only two call sites, and the second one (line 199) is inside a test permanently disabled by @skipIf(True, ...), so signing this request touches nothing else.

As written, the explicit-HttpApi and AutoPublishAlias+HttpApi-event paths lose their IAM authorizer coverage while sibling HttpApi templates keep it, leaving the suite inconsistent about which HttpApi templates are authorized.

Suggested alternative — keep the auth in both templates and sign the request:

deftest_function_with_http_api_events(self, file_name):
self.create_and_verify_stack(file_name)
endpoint=self.get_api_v2_endpoint("MyHttpApi")
response=self.verify_get_request_response_sigv4(endpoint, 200)
self.assertEqual(response.text, self.FUNCTION_OUTPUT)

If dropping the auth is the deliberate choice, please state the reason for these two templates in the description as you did for Issues 1 and 2, so the coverage loss is a recorded decision rather than an unexplained diff.

@aws-sam-tooling-botaws-sam-tooling-botBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Results

Reviewed: bf2378c..be82639
Files: 8
Comments: 1

Comment threadintegration/single/test_basic_function.py
@licjun
licjun merged commit ab5503a into developAug 12, 2026
9 checks passed
@licjun
licjun deleted the fix/websocket-auth-connect-route branch August 12, 2026 23:29
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@licjun@vicheey@reedham-aws
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' fix(integ-tests): resolve remaining API Gateway auth failures by licjun · Pull Request #3972 · aws/serverless-application-model · GitHub
Skip to content

fix(integ-tests): resolve remaining API Gateway auth failures - #3972

Merged
licjun merged 4 commits into
developfrom
fix/websocket-auth-connect-route
Aug 12, 2026
Merged

fix(integ-tests): resolve remaining API Gateway auth failures#3972
licjun merged 4 commits into
developfrom
fix/websocket-auth-connect-route

Conversation

@licjun

@licjunlicjun commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #3963 and #3967. Resolves the remaining integration test failures introduced when IAM auth was added to the test templates.

Auth is only removed where the SAM transform makes it impossible. Where auth is valid, it is kept and the test request is signed instead.

Issue 1 — WebSocket auth requires a $connect route

Six templates configure only a $default route, so the transform failed:

Resource with id [MyApi] is invalid. Authorization is only available if there is a $connect route.

These templates intentionally cover minimal WebSocket configurations, so adding a $connect route would change what they test. Auth is removed instead:

  • websocket_api_basic.yaml
  • websocket_api_basic_config.yaml
  • websocket_api_custom_domains_regional.yaml
  • websocket_api_multiple_api.yaml (both Api1 and Api2)
  • websocket_api_route_settings.yaml
  • websocket_api_stage_config.yaml

Dedicated IAM auth coverage for WebSocket APIs remains in test_websocket_api_with_auth.py, and every template that keeps AuthType: AWS_IAM has a $connect route.

Issue 2 — unsigned requests against authenticated APIs

Two tests issue unsigned requests against APIs that gained IAM auth, returning 403 where 200 was expected:

AssertionError: 403 != 200 : must return HTTP 200

The affected templates use an inline DefinitionBody (REST) or AWS::Serverless::HttpApi, so IAM auth is valid for them. The auth is kept and the requests are signed, matching the existing pattern in test_function_with_http_api.py and test_function_with_implicit_http_api.py:

test_binary_media_types_with_definition_body_openapicombination/api_with_binary_media_types_with_definition_body_openapi.yaml

 def verify_binary_media_request(self, url, expected_status_code):
headers = {"accept": "image/png"}
- response = self.do_get_request_with_logging(url, headers)+ response = self.do_get_request_with_sigv4(url, headers)

test_function_with_http_api_eventssingle/function_with_http_api_events.yaml and single/function_alias_with_http_api_events.yaml

 endpoint = self.get_api_v2_endpoint("MyHttpApi")
- self._verify_get_request(endpoint, self.FUNCTION_OUTPUT)+ response = self.verify_get_request_response_sigv4(endpoint, 200)+ self.assertEqual(response.text, self.FUNCTION_OUTPUT)

Signing is applied at the call site rather than inside the shared _verify_get_request helper, since that helper is also used by a Lambda function URL test.

Testing

Verified in account 830899278857.

us-west-2 — each affected test confirmed:

TestResult
test_binary_media_types_with_definition_body_openapiPASSED
test_function_with_http_api_events (both parameterized cases)PASSED
test_websocket_api_basicPASSED
test_websocket_api_basic_configPASSED
test_websocket_multi_apiPASSED
test_websocket_api_route_settingsPASSED
test_websocket_api_stage_configPASSED

Full test_api_settings.py also run: 9 passed, 1 xpassed.

For the binary-media failure, all three configurations were tested to confirm the diagnosis:

Template authTest requestResult
AWS_IAMunsigned (state on develop)403 — reproduces the failure
AWS_IAMSigV4 (this PR)passes
noneunsignedpasses

us-east-1 — the 4 custom-domain tests pass (CustomDomain is only enabled there):

  • test_custom_http_api_domains_regional + ..._ownership_verification
  • test_custom_rest_api_domains_edge (+ regional, regional_ownership_verification)
  • test_websocket_custom_api_domains_regional

ruff check passes on both modified test files. The two ruff format warnings on them also occur on a clean develop, so they are left untouched to avoid unrelated reformatting.

@licjun
licjun requested a review from a team as a code ownerAugust 12, 2026 22:03

@aws-sam-tooling-botaws-sam-tooling-botBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Results

Reviewed: bf2378c..fe414f2
Files: 7
Comments: 1

Comment threadintegration/combination/test_api_settings.py

@aws-sam-tooling-botaws-sam-tooling-botBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Results

Reviewed: bf2378c..8bfe4d7
Files: 7
Comments: 2


Comments on lines outside the diff:

[integration/resources/templates/combination/api_with_binary_media_types_with_definition_body_openapi.yaml:28][GENERAL] This change does not match the approach described in the PR. The description states that for this template IAM auth is valid there — so the auth is kept and the request is signed instead, with this diff:

- response = self.do_get_request_with_logging(url, headers)+ response = self.do_get_request_with_sigv4(url, headers)

But the actual change removes the Auth block from this template, and integration/combination/test_api_settings.py is not part of the diff at all — verify_binary_media_request (line 161) still calls the unsigned do_get_request_with_logging. The test will pass, but only because the endpoint is now unauthenticated, which reverts the #3963 intent for a template where IAM auth demonstrably works (it uses DefinitionBody, so the transform accepts DefaultAuthorizer: AWS_IAM).

Either restore the auth and sign the request, or update the PR description to state that auth is being dropped here too. The signing helper already exists in integration/helpers/base_test.py:

defverify_binary_media_request(self, url, expected_status_code):
headers= {"accept": "image/png"}
response=self.do_get_request_with_sigv4(url, headers)

[integration/resources/templates/combination/api_with_binary_media_types_with_definition_body_openapi.yaml:29][BUG] Re-raising an unresolved issue from the previous review (not dismissed by the author): the same unsigned-request-against-IAM-auth failure still exists in integration/single/test_basic_function.py, so the "resolves the two remaining auth failures" claim is incomplete.

test_function_with_http_api_events (line 70) runs against single/function_with_http_api_events and single/function_alias_with_http_api_events. Both templates carry IAM auth:

MyHttpApi:
Type: AWS::Serverless::HttpApiProperties:
Auth:
EnableIamAuthorizer: trueDefaultAuthorizer: AWS_IAM

The test then calls self._verify_get_request(endpoint, self.FUNCTION_OUTPUT) (line 75), which delegates to verify_get_request_response(url, 200) — the unsigned path (do_get_request_with_logging, base_test.py:537). API Gateway will return 403, so the assertion fails the same way test_binary_media_types_with_definition_body_openapi did. The @pytest.mark.flaky(reruns=5) decorator and the tenacity retry will not help, since the failure is deterministic.

Sibling tests already use the signed helper (test_function_with_http_api.py, test_function_with_implicit_http_api.py call verify_get_request_response_sigv4), so the consistent fix is:

defverifyget_request(self, url, expected_text):
response=self.verify_get_request_response_sigv4(url, 200)
self.assertEqual(response.text, expected_text)

Note that _verify_get_request is also used at line 199 for a Lambda function URL test, so if that URL is not IAM-authenticated, sign only the HTTP API call site rather than changing the shared helper.

@aws-sam-tooling-botaws-sam-tooling-botBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Results

Reviewed: bf2378c..fe03cfb
Files: 9
Comments: 1


Comments on lines outside the diff:

[integration/resources/templates/single/function_with_http_api_events.yaml:3][GENERAL] This file and function_alias_with_http_api_events.yaml drop EnableIamAuthorizer/DefaultAuthorizer: AWS_IAM, but neither is covered by the two issues in the PR description (Issue 1 lists six WebSocket templates, Issue 2 lists the binary-media template). These two templates fail for the third reason raised in the previous review: test_function_with_http_api_events calls self._verify_get_request(endpoint, ...) (integration/single/test_basic_function.py:75), which goes through verify_get_request_responsedo_get_request_with_logging, i.e. an unsigned request against an IAM-authorized API.

For that failure mode the codebase already has an established fix that keeps the auth coverage: verify_get_request_response_sigv4, used by test_function_with_http_api and test_function_with_implicit_http_api for templates that retain EnableIamAuthorizer (integration/combination/test_function_with_http_api.py:21-32, integration/combination/test_function_with_implicit_http_api.py:15-17). The description's rationale for preferring removal — "avoids changing shared test helpers" — does not apply here: _verify_get_request is a private helper in test_basic_function.py with only two call sites, and the second one (line 199) is inside a test permanently disabled by @skipIf(True, ...), so signing this request touches nothing else.

As written, the explicit-HttpApi and AutoPublishAlias+HttpApi-event paths lose their IAM authorizer coverage while sibling HttpApi templates keep it, leaving the suite inconsistent about which HttpApi templates are authorized.

Suggested alternative — keep the auth in both templates and sign the request:

deftest_function_with_http_api_events(self, file_name):
self.create_and_verify_stack(file_name)
endpoint=self.get_api_v2_endpoint("MyHttpApi")
response=self.verify_get_request_response_sigv4(endpoint, 200)
self.assertEqual(response.text, self.FUNCTION_OUTPUT)

If dropping the auth is the deliberate choice, please state the reason for these two templates in the description as you did for Issues 1 and 2, so the coverage loss is a recorded decision rather than an unexplained diff.

@aws-sam-tooling-botaws-sam-tooling-botBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Results

Reviewed: bf2378c..be82639
Files: 8
Comments: 1

Comment threadintegration/single/test_basic_function.py
@licjun
licjun merged commit ab5503a into developAug 12, 2026
9 checks passed
@licjun
licjun deleted the fix/websocket-auth-connect-route branch August 12, 2026 23:29
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@licjun@vicheey@reedham-aws
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' fix(integ-tests): resolve remaining API Gateway auth failures by licjun · Pull Request #3972 · aws/serverless-application-model · GitHub
Skip to content

fix(integ-tests): resolve remaining API Gateway auth failures - #3972

Merged
licjun merged 4 commits into
developfrom
fix/websocket-auth-connect-route
Aug 12, 2026
Merged

fix(integ-tests): resolve remaining API Gateway auth failures#3972
licjun merged 4 commits into
developfrom
fix/websocket-auth-connect-route

Conversation

@licjun

@licjunlicjun commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #3963 and #3967. Resolves the remaining integration test failures introduced when IAM auth was added to the test templates.

Auth is only removed where the SAM transform makes it impossible. Where auth is valid, it is kept and the test request is signed instead.

Issue 1 — WebSocket auth requires a $connect route

Six templates configure only a $default route, so the transform failed:

Resource with id [MyApi] is invalid. Authorization is only available if there is a $connect route.

These templates intentionally cover minimal WebSocket configurations, so adding a $connect route would change what they test. Auth is removed instead:

  • websocket_api_basic.yaml
  • websocket_api_basic_config.yaml
  • websocket_api_custom_domains_regional.yaml
  • websocket_api_multiple_api.yaml (both Api1 and Api2)
  • websocket_api_route_settings.yaml
  • websocket_api_stage_config.yaml

Dedicated IAM auth coverage for WebSocket APIs remains in test_websocket_api_with_auth.py, and every template that keeps AuthType: AWS_IAM has a $connect route.

Issue 2 — unsigned requests against authenticated APIs

Two tests issue unsigned requests against APIs that gained IAM auth, returning 403 where 200 was expected:

AssertionError: 403 != 200 : must return HTTP 200

The affected templates use an inline DefinitionBody (REST) or AWS::Serverless::HttpApi, so IAM auth is valid for them. The auth is kept and the requests are signed, matching the existing pattern in test_function_with_http_api.py and test_function_with_implicit_http_api.py:

test_binary_media_types_with_definition_body_openapicombination/api_with_binary_media_types_with_definition_body_openapi.yaml

 def verify_binary_media_request(self, url, expected_status_code):
headers = {"accept": "image/png"}
- response = self.do_get_request_with_logging(url, headers)+ response = self.do_get_request_with_sigv4(url, headers)

test_function_with_http_api_eventssingle/function_with_http_api_events.yaml and single/function_alias_with_http_api_events.yaml

 endpoint = self.get_api_v2_endpoint("MyHttpApi")
- self._verify_get_request(endpoint, self.FUNCTION_OUTPUT)+ response = self.verify_get_request_response_sigv4(endpoint, 200)+ self.assertEqual(response.text, self.FUNCTION_OUTPUT)

Signing is applied at the call site rather than inside the shared _verify_get_request helper, since that helper is also used by a Lambda function URL test.

Testing

Verified in account 830899278857.

us-west-2 — each affected test confirmed:

TestResult
test_binary_media_types_with_definition_body_openapiPASSED
test_function_with_http_api_events (both parameterized cases)PASSED
test_websocket_api_basicPASSED
test_websocket_api_basic_configPASSED
test_websocket_multi_apiPASSED
test_websocket_api_route_settingsPASSED
test_websocket_api_stage_configPASSED

Full test_api_settings.py also run: 9 passed, 1 xpassed.

For the binary-media failure, all three configurations were tested to confirm the diagnosis:

Template authTest requestResult
AWS_IAMunsigned (state on develop)403 — reproduces the failure
AWS_IAMSigV4 (this PR)passes
noneunsignedpasses

us-east-1 — the 4 custom-domain tests pass (CustomDomain is only enabled there):

  • test_custom_http_api_domains_regional + ..._ownership_verification
  • test_custom_rest_api_domains_edge (+ regional, regional_ownership_verification)
  • test_websocket_custom_api_domains_regional

ruff check passes on both modified test files. The two ruff format warnings on them also occur on a clean develop, so they are left untouched to avoid unrelated reformatting.

@licjun
licjun requested a review from a team as a code ownerAugust 12, 2026 22:03

@aws-sam-tooling-botaws-sam-tooling-botBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Results

Reviewed: bf2378c..fe414f2
Files: 7
Comments: 1

Comment threadintegration/combination/test_api_settings.py

@aws-sam-tooling-botaws-sam-tooling-botBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Results

Reviewed: bf2378c..8bfe4d7
Files: 7
Comments: 2


Comments on lines outside the diff:

[integration/resources/templates/combination/api_with_binary_media_types_with_definition_body_openapi.yaml:28][GENERAL] This change does not match the approach described in the PR. The description states that for this template IAM auth is valid there — so the auth is kept and the request is signed instead, with this diff:

- response = self.do_get_request_with_logging(url, headers)+ response = self.do_get_request_with_sigv4(url, headers)

But the actual change removes the Auth block from this template, and integration/combination/test_api_settings.py is not part of the diff at all — verify_binary_media_request (line 161) still calls the unsigned do_get_request_with_logging. The test will pass, but only because the endpoint is now unauthenticated, which reverts the #3963 intent for a template where IAM auth demonstrably works (it uses DefinitionBody, so the transform accepts DefaultAuthorizer: AWS_IAM).

Either restore the auth and sign the request, or update the PR description to state that auth is being dropped here too. The signing helper already exists in integration/helpers/base_test.py:

defverify_binary_media_request(self, url, expected_status_code):
headers= {"accept": "image/png"}
response=self.do_get_request_with_sigv4(url, headers)

[integration/resources/templates/combination/api_with_binary_media_types_with_definition_body_openapi.yaml:29][BUG] Re-raising an unresolved issue from the previous review (not dismissed by the author): the same unsigned-request-against-IAM-auth failure still exists in integration/single/test_basic_function.py, so the "resolves the two remaining auth failures" claim is incomplete.

test_function_with_http_api_events (line 70) runs against single/function_with_http_api_events and single/function_alias_with_http_api_events. Both templates carry IAM auth:

MyHttpApi:
Type: AWS::Serverless::HttpApiProperties:
Auth:
EnableIamAuthorizer: trueDefaultAuthorizer: AWS_IAM

The test then calls self._verify_get_request(endpoint, self.FUNCTION_OUTPUT) (line 75), which delegates to verify_get_request_response(url, 200) — the unsigned path (do_get_request_with_logging, base_test.py:537). API Gateway will return 403, so the assertion fails the same way test_binary_media_types_with_definition_body_openapi did. The @pytest.mark.flaky(reruns=5) decorator and the tenacity retry will not help, since the failure is deterministic.

Sibling tests already use the signed helper (test_function_with_http_api.py, test_function_with_implicit_http_api.py call verify_get_request_response_sigv4), so the consistent fix is:

defverifyget_request(self, url, expected_text):
response=self.verify_get_request_response_sigv4(url, 200)
self.assertEqual(response.text, expected_text)

Note that _verify_get_request is also used at line 199 for a Lambda function URL test, so if that URL is not IAM-authenticated, sign only the HTTP API call site rather than changing the shared helper.

@aws-sam-tooling-botaws-sam-tooling-botBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Results

Reviewed: bf2378c..fe03cfb
Files: 9
Comments: 1


Comments on lines outside the diff:

[integration/resources/templates/single/function_with_http_api_events.yaml:3][GENERAL] This file and function_alias_with_http_api_events.yaml drop EnableIamAuthorizer/DefaultAuthorizer: AWS_IAM, but neither is covered by the two issues in the PR description (Issue 1 lists six WebSocket templates, Issue 2 lists the binary-media template). These two templates fail for the third reason raised in the previous review: test_function_with_http_api_events calls self._verify_get_request(endpoint, ...) (integration/single/test_basic_function.py:75), which goes through verify_get_request_responsedo_get_request_with_logging, i.e. an unsigned request against an IAM-authorized API.

For that failure mode the codebase already has an established fix that keeps the auth coverage: verify_get_request_response_sigv4, used by test_function_with_http_api and test_function_with_implicit_http_api for templates that retain EnableIamAuthorizer (integration/combination/test_function_with_http_api.py:21-32, integration/combination/test_function_with_implicit_http_api.py:15-17). The description's rationale for preferring removal — "avoids changing shared test helpers" — does not apply here: _verify_get_request is a private helper in test_basic_function.py with only two call sites, and the second one (line 199) is inside a test permanently disabled by @skipIf(True, ...), so signing this request touches nothing else.

As written, the explicit-HttpApi and AutoPublishAlias+HttpApi-event paths lose their IAM authorizer coverage while sibling HttpApi templates keep it, leaving the suite inconsistent about which HttpApi templates are authorized.

Suggested alternative — keep the auth in both templates and sign the request:

deftest_function_with_http_api_events(self, file_name):
self.create_and_verify_stack(file_name)
endpoint=self.get_api_v2_endpoint("MyHttpApi")
response=self.verify_get_request_response_sigv4(endpoint, 200)
self.assertEqual(response.text, self.FUNCTION_OUTPUT)

If dropping the auth is the deliberate choice, please state the reason for these two templates in the description as you did for Issues 1 and 2, so the coverage loss is a recorded decision rather than an unexplained diff.

@aws-sam-tooling-botaws-sam-tooling-botBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Results

Reviewed: bf2378c..be82639
Files: 8
Comments: 1

Comment threadintegration/single/test_basic_function.py
@licjun
licjun merged commit ab5503a into developAug 12, 2026
9 checks passed
@licjun
licjun deleted the fix/websocket-auth-connect-route branch August 12, 2026 23:29
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@licjun@vicheey@reedham-aws
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); fix(integ-tests): resolve remaining API Gateway auth failures by licjun · Pull Request #3972 · aws/serverless-application-model · GitHub
Skip to content

fix(integ-tests): resolve remaining API Gateway auth failures - #3972

Merged
licjun merged 4 commits into
developfrom
fix/websocket-auth-connect-route
Aug 12, 2026
Merged

fix(integ-tests): resolve remaining API Gateway auth failures#3972
licjun merged 4 commits into
developfrom
fix/websocket-auth-connect-route

Conversation

@licjun

@licjunlicjun commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #3963 and #3967. Resolves the remaining integration test failures introduced when IAM auth was added to the test templates.

Auth is only removed where the SAM transform makes it impossible. Where auth is valid, it is kept and the test request is signed instead.

Issue 1 — WebSocket auth requires a $connect route

Six templates configure only a $default route, so the transform failed:

Resource with id [MyApi] is invalid. Authorization is only available if there is a $connect route.

These templates intentionally cover minimal WebSocket configurations, so adding a $connect route would change what they test. Auth is removed instead:

  • websocket_api_basic.yaml
  • websocket_api_basic_config.yaml
  • websocket_api_custom_domains_regional.yaml
  • websocket_api_multiple_api.yaml (both Api1 and Api2)
  • websocket_api_route_settings.yaml
  • websocket_api_stage_config.yaml

Dedicated IAM auth coverage for WebSocket APIs remains in test_websocket_api_with_auth.py, and every template that keeps AuthType: AWS_IAM has a $connect route.

Issue 2 — unsigned requests against authenticated APIs

Two tests issue unsigned requests against APIs that gained IAM auth, returning 403 where 200 was expected:

AssertionError: 403 != 200 : must return HTTP 200

The affected templates use an inline DefinitionBody (REST) or AWS::Serverless::HttpApi, so IAM auth is valid for them. The auth is kept and the requests are signed, matching the existing pattern in test_function_with_http_api.py and test_function_with_implicit_http_api.py:

test_binary_media_types_with_definition_body_openapicombination/api_with_binary_media_types_with_definition_body_openapi.yaml

 def verify_binary_media_request(self, url, expected_status_code):
headers = {"accept": "image/png"}
- response = self.do_get_request_with_logging(url, headers)+ response = self.do_get_request_with_sigv4(url, headers)

test_function_with_http_api_eventssingle/function_with_http_api_events.yaml and single/function_alias_with_http_api_events.yaml

 endpoint = self.get_api_v2_endpoint("MyHttpApi")
- self._verify_get_request(endpoint, self.FUNCTION_OUTPUT)+ response = self.verify_get_request_response_sigv4(endpoint, 200)+ self.assertEqual(response.text, self.FUNCTION_OUTPUT)

Signing is applied at the call site rather than inside the shared _verify_get_request helper, since that helper is also used by a Lambda function URL test.

Testing

Verified in account 830899278857.

us-west-2 — each affected test confirmed:

TestResult
test_binary_media_types_with_definition_body_openapiPASSED
test_function_with_http_api_events (both parameterized cases)PASSED
test_websocket_api_basicPASSED
test_websocket_api_basic_configPASSED
test_websocket_multi_apiPASSED
test_websocket_api_route_settingsPASSED
test_websocket_api_stage_configPASSED

Full test_api_settings.py also run: 9 passed, 1 xpassed.

For the binary-media failure, all three configurations were tested to confirm the diagnosis:

Template authTest requestResult
AWS_IAMunsigned (state on develop)403 — reproduces the failure
AWS_IAMSigV4 (this PR)passes
noneunsignedpasses

us-east-1 — the 4 custom-domain tests pass (CustomDomain is only enabled there):

  • test_custom_http_api_domains_regional + ..._ownership_verification
  • test_custom_rest_api_domains_edge (+ regional, regional_ownership_verification)
  • test_websocket_custom_api_domains_regional

ruff check passes on both modified test files. The two ruff format warnings on them also occur on a clean develop, so they are left untouched to avoid unrelated reformatting.

@licjun
licjun requested a review from a team as a code ownerAugust 12, 2026 22:03

@aws-sam-tooling-botaws-sam-tooling-botBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Results

Reviewed: bf2378c..fe414f2
Files: 7
Comments: 1

Comment threadintegration/combination/test_api_settings.py

@aws-sam-tooling-botaws-sam-tooling-botBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Results

Reviewed: bf2378c..8bfe4d7
Files: 7
Comments: 2


Comments on lines outside the diff:

[integration/resources/templates/combination/api_with_binary_media_types_with_definition_body_openapi.yaml:28][GENERAL] This change does not match the approach described in the PR. The description states that for this template IAM auth is valid there — so the auth is kept and the request is signed instead, with this diff:

- response = self.do_get_request_with_logging(url, headers)+ response = self.do_get_request_with_sigv4(url, headers)

But the actual change removes the Auth block from this template, and integration/combination/test_api_settings.py is not part of the diff at all — verify_binary_media_request (line 161) still calls the unsigned do_get_request_with_logging. The test will pass, but only because the endpoint is now unauthenticated, which reverts the #3963 intent for a template where IAM auth demonstrably works (it uses DefinitionBody, so the transform accepts DefaultAuthorizer: AWS_IAM).

Either restore the auth and sign the request, or update the PR description to state that auth is being dropped here too. The signing helper already exists in integration/helpers/base_test.py:

defverify_binary_media_request(self, url, expected_status_code):
headers= {"accept": "image/png"}
response=self.do_get_request_with_sigv4(url, headers)

[integration/resources/templates/combination/api_with_binary_media_types_with_definition_body_openapi.yaml:29][BUG] Re-raising an unresolved issue from the previous review (not dismissed by the author): the same unsigned-request-against-IAM-auth failure still exists in integration/single/test_basic_function.py, so the "resolves the two remaining auth failures" claim is incomplete.

test_function_with_http_api_events (line 70) runs against single/function_with_http_api_events and single/function_alias_with_http_api_events. Both templates carry IAM auth:

MyHttpApi:
Type: AWS::Serverless::HttpApiProperties:
Auth:
EnableIamAuthorizer: trueDefaultAuthorizer: AWS_IAM

The test then calls self._verify_get_request(endpoint, self.FUNCTION_OUTPUT) (line 75), which delegates to verify_get_request_response(url, 200) — the unsigned path (do_get_request_with_logging, base_test.py:537). API Gateway will return 403, so the assertion fails the same way test_binary_media_types_with_definition_body_openapi did. The @pytest.mark.flaky(reruns=5) decorator and the tenacity retry will not help, since the failure is deterministic.

Sibling tests already use the signed helper (test_function_with_http_api.py, test_function_with_implicit_http_api.py call verify_get_request_response_sigv4), so the consistent fix is:

defverifyget_request(self, url, expected_text):
response=self.verify_get_request_response_sigv4(url, 200)
self.assertEqual(response.text, expected_text)

Note that _verify_get_request is also used at line 199 for a Lambda function URL test, so if that URL is not IAM-authenticated, sign only the HTTP API call site rather than changing the shared helper.

@aws-sam-tooling-botaws-sam-tooling-botBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Results

Reviewed: bf2378c..fe03cfb
Files: 9
Comments: 1


Comments on lines outside the diff:

[integration/resources/templates/single/function_with_http_api_events.yaml:3][GENERAL] This file and function_alias_with_http_api_events.yaml drop EnableIamAuthorizer/DefaultAuthorizer: AWS_IAM, but neither is covered by the two issues in the PR description (Issue 1 lists six WebSocket templates, Issue 2 lists the binary-media template). These two templates fail for the third reason raised in the previous review: test_function_with_http_api_events calls self._verify_get_request(endpoint, ...) (integration/single/test_basic_function.py:75), which goes through verify_get_request_responsedo_get_request_with_logging, i.e. an unsigned request against an IAM-authorized API.

For that failure mode the codebase already has an established fix that keeps the auth coverage: verify_get_request_response_sigv4, used by test_function_with_http_api and test_function_with_implicit_http_api for templates that retain EnableIamAuthorizer (integration/combination/test_function_with_http_api.py:21-32, integration/combination/test_function_with_implicit_http_api.py:15-17). The description's rationale for preferring removal — "avoids changing shared test helpers" — does not apply here: _verify_get_request is a private helper in test_basic_function.py with only two call sites, and the second one (line 199) is inside a test permanently disabled by @skipIf(True, ...), so signing this request touches nothing else.

As written, the explicit-HttpApi and AutoPublishAlias+HttpApi-event paths lose their IAM authorizer coverage while sibling HttpApi templates keep it, leaving the suite inconsistent about which HttpApi templates are authorized.

Suggested alternative — keep the auth in both templates and sign the request:

deftest_function_with_http_api_events(self, file_name):
self.create_and_verify_stack(file_name)
endpoint=self.get_api_v2_endpoint("MyHttpApi")
response=self.verify_get_request_response_sigv4(endpoint, 200)
self.assertEqual(response.text, self.FUNCTION_OUTPUT)

If dropping the auth is the deliberate choice, please state the reason for these two templates in the description as you did for Issues 1 and 2, so the coverage loss is a recorded decision rather than an unexplained diff.

@aws-sam-tooling-botaws-sam-tooling-botBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Results

Reviewed: bf2378c..be82639
Files: 8
Comments: 1

Comment threadintegration/single/test_basic_function.py
@licjun
licjun merged commit ab5503a into developAug 12, 2026
9 checks passed
@licjun
licjun deleted the fix/websocket-auth-connect-route branch August 12, 2026 23:29
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@licjun@vicheey@reedham-aws