Skip to content

feat: improve AuthType validation for WebSocketApi - #3990

Merged
roger-zhangg merged 1 commit into
aws:developfrom
valerena:websocket-authtype-validation
Sep 2, 2026
Merged

roger-zhangg merged 1 commit into
aws:developfrom
valerena:websocket-authtype-validation

Conversation

@valerena

@valerena valerena commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Issue #, if available

Invalid values that looked like correct values but with the wrong casing, were previously being ignored, because their value was passing validation but it wasn't recognized as valid, and eventually being translated to NONE.

Description of changes

The templates that had AuthType values with the wrong casing now will explicitly fail instead of silently being ignored. A consequence of this is that templates that were using None or none, which were having "the expected behavior" of having "no auth", will now also fail (just like other mismatched casing of valid values).

This is a backwards-incompatible change, which we accept in favor of stricter validation. Existing deployed stacks won't change on their own, but the next transform will fail until the user corrects the invalid value.

We also improved the error message returned, so any customer can clearly see the specific value that they passed that was invalid.

The WebSocketApi resource was launched earlier this year, and its usage is low compared to other resources. This situation with AuthType is a niche issue that is limited to a very small portion of customers, and that's why accept the backwards incompatibility.

Description of how you validated changes

  • make pr
  • Add extra tests.

Checklist

Examples?

Please reach out in the comments if you want to add an example. Examples will be
added to sam init through aws/aws-sam-cli-app-templates.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Invalid values that looked like correct values, but with the wrong casing
were previously being ignored, because their value was passing validation,
but it wasn't recognized as valid and eventually being translated to `NONE`.
Now they will explicitly fail. A consequence of this is that templates that
were using `None` or `none`, which were having "the expected behavior" of
having "no auth", will now also fail (just like other mismatched casing of
valid values).

This is a backwards-incompatible change, which we accept in favor of
stricter validation. Existing deployed stacks won't change on their own,
but  the next transform will fail until the user corrects the invalid value.
@valerena
valerena requested a review from a team as a code owner September 2, 2026 19:06

@aws-sam-tooling-bot aws-sam-tooling-bot Bot 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: 1201464..dd94666
Files: 6
Comments: 1


Comments on lines outside the diff:

[samtranslator/model/api/websocket_api_generator.py:216] [INPUT_VALIDATION] Now that the value is compared verbatim, this check should also account for AuthType not being a plain string. The schema declares it as a pass-through prop (AuthType: PassThroughProp in internal/schema_source/aws_serverless_websocketapi.py), and SamWebSocketApi.to_cloudformation only runs resolve_parameter_refs on Auth — that resolves Refs to template parameters, but Fn::If, Fn::FindInMap, and Fn::GetAtt reach here as a dict.

The result is a customer-facing message containing a raw Python dict, e.g.:

Resource with id [MyApi] is invalid. AuthType '{'Fn::If': ['IsProd', 'AWS_IAM', 'NONE']}' is not one of AWS_IAM, CUSTOM or NONE.

This is not a regression — previously auth_type.upper() raised AttributeError on the same input, which is worse — but since this PR rewrites exactly this validation and its error message, it's the natural place to handle it. The same class already establishes the pattern for a value-set check on an intrinsic-capable property:

if (
   self.ip_address_type is not None
   and not is_intrinsic(self.ip_address_type)
   and self.ip_address_type not in ("ipv4", "dualstack")
):
   raise InvalidResourceException(self.logical_id, "IpAddressType must be 'ipv4' or 'dualstack'.")

Applying it here keeps behavior consistent across the resource (is_intrinsic is already imported). Note this decides intent: skipping intrinsics lets unresolved intrinsics through to the downstream == AuthType.CUSTOM comparisons, which would silently land on AuthorizationType: NONE — the very failure mode this PR fixes. If intrinsics are meant to be unsupported, prefer an explicit rejection with a message that says so rather than one that reports the dict as an invalid enum value:

if not isinstance(auth_type, str):
   raise InvalidResourceException(self.logical_id, "AuthType must be one of AWS_IAM, CUSTOM or NONE.")

@valerena

valerena commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

From the bot comment:

This is not a regression — previously auth_type.upper() raised AttributeError on the same input, which is worse

This is correct. We've never supported intrinsics on this field (CUSTOM requires more properties to be passed, so it would be hard to use intrinsics only for the value of AuthType). So for now it's okay. We haven't seen data about anyone running into this issue, but we might support it in the future if we hear from customers.

@valerena
valerena enabled auto-merge (squash) September 2, 2026 19:49
@roger-zhangg
roger-zhangg merged commit d24401d into aws:develop Sep 2, 2026
8 of 9 checks passed
Sign up for free to 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