Skip to content

fix(integration-tests): make MyFirstApiKey value stack-scoped - #3997

Merged
licjun merged 1 commit into
aws:developfrom
licjun:fix/integ-test-api-key-value-collision
Sep 25, 2026
Merged

licjun merged 1 commit into
aws:developfrom
licjun:fix/integ-test-api-key-value-collision

Conversation

@licjun

@licjun licjun commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

Problem

The api_with_authorizer_apikey integration test template hardcodes both the AWS::ApiGateway::ApiKey.Value and the Lambda authorizer's usageIdentifierKey to the literal "needatleast20characters".

AWS API Gateway enforces an undocumented uniqueness constraint on value across account + region (returns 409 ConflictException / HandlerErrorCode: AlreadyExists on collision). Any leftover key from a previous run — for example, a test runner that timed out before cleanup could complete — will collide with the next run's stack creation, and the stack rolls back to ROLLBACK_COMPLETE. Both the first attempt and any --reruns retry hit the same collision (same hardcoded literal), so the test fails deterministically until the orphaned key is deleted externally.

Fix

Substitute ${AWS::StackName} into both Value and the authorizer's usageIdentifierKey. Because ${AWS::StackName} is unique per CFN stack (which is unique per run), the API Key value is unique per run, and the authorizer + key still resolve to the same string at runtime.

Length bounds (empirically verified)

  • CreateApiKey.value min = 20 characters ("API Key value should be at least 20 characters")
  • CreateApiKey.value max = 128 characters ("API Key value exceeds maximum size of 128 characters")
  • Substituted length is 19 (prefix "needatleast20chars-") + len(stackName). For representative integration-test stack names (~60–70 characters), the result is well within [20, 128].

Testing

Verified end-to-end in a dev account:

  • Deployed the fixed template twice with different stack names (fix-test-stack-alpha and fix-test-stack-beta) — both CREATE_COMPLETE, no AlreadyExists collision (previously, one of the two would fail with this signature).
  • Confirmed each stack's API Key value equals needatleast20chars-<stackName> (i.e., ${AWS::StackName} is correctly substituted at deploy time).
  • Confirmed runtime behavior: GET /lambda-token-api-key with Authorization: allow returns 200 (authorizer's usageIdentifierKey matches the API Key value → usage plan matches), and Authorization: deny returns 403.
  • The corresponding test (integration/combination/test_api_with_authorizer_apikey.py) reads the API Key value from AWS at runtime (get_api_key(..., includeValue=True)) and does not depend on any specific literal, so no test-code changes are needed.

The api_with_authorizer_apikey template hardcodes both the API Key's
Value and the Lambda authorizer's usageIdentifierKey to the literal
"needatleast20characters". AWS API Gateway enforces an undocumented
uniqueness constraint on the API Key value across account+region
(returns 409 ConflictException with HandlerErrorCode: AlreadyExists
on collision). Any orphaned resource from a previous run - for
example, a test runner that timed out before its cleanup could
complete - will hold the value and block every subsequent run of
this test until the orphan is deleted externally.

Scope the API Key value to ${AWS::StackName} so it is unique per
CFN stack, while still matching the authorizer's usageIdentifierKey.
Substituted length stays within API Gateway's [20, 128]-character
bounds (empirically verified: min=20 with "API Key value should be
at least 20 characters", max=128 with "API Key value exceeds
maximum size of 128 characters"). Verified end-to-end by deploying
the fixed template as two concurrent stacks in a dev account -
both created cleanly with distinct stack-scoped values, and the
runtime authorizer flow returned 200 for allow / 403 for deny.
@licjun
licjun requested a review from a team as a code owner September 23, 2026 22:53
@licjun
licjun merged commit ebcce20 into aws:develop Sep 25, 2026
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