Skip to content

fix(apigatewayv2): resolve HTTP API region across regions like REST APIs do - #2149

Open
rogueserenity wants to merge 3 commits into
floci-io:mainfrom
rogueserenity:fix/httpapi-execute-region-resolution
Open

fix(apigatewayv2): resolve HTTP API region across regions like REST APIs do#2149
rogueserenity wants to merge 3 commits into
floci-io:mainfrom
rogueserenity:fix/httpapi-execute-region-resolution

Conversation

@rogueserenity

Copy link
Copy Markdown
Contributor

Summary

Unsigned requests (and requests carrying a non-SigV4 Authorization header, e.g. a Cognito bearer JWT) resolve to RegionResolver's configured default region rather than a region the caller specified. For v1 REST APIs, resolveRestApiRegion already falls back to scanning all regions for the apiId when that happens. HTTP API (v2) dispatch had no equivalent, so any HTTP API deployed outside the default region returned 404 "Invalid API id specified" for every unsigned or bearer-token-authenticated request — which is effectively every request a browser, curl, or non-SigV4 client sends.

What changed

  • Adds ApiGatewayV2Service#resolveHttpApiRegion, mirroring ApiGatewayService#resolveRestApiRegion exactly (same region::apiId key shape).
  • Adds RegionResolver#isRegionUnresolved to give dispatch() a single correct signal for "region resolution silently fell back to the default" — this covers both the blank-header case the previous check handled and the non-SigV4-header case it missed (a bearer JWT is a non-empty Authorization header that still isn't a region signal).
  • dispatch() now consults the fallback scan for v2 the same way it already does for v1. As a side effect this also widens the existing v1 fallback from "blank Authorization header only" to "any Authorization header that didn't resolve a real region" — the same latent bug existed on the REST API path for bearer-JWT-authenticated requests and is fixed here too.

Test plan

  • unsignedRequestFindsV2ApiDeployedOutsideDefaultRegion: an unsigned request for a v2 API deployed outside the default region falls back to resolveHttpApiRegion and finds it.
  • signedV2RequestDoesNotConsultRegionFallback: a request whose region resolved correctly never pays for the fallback scan.
  • nonSigV4AuthorizationHeaderFallsBackToRestApiRegionScan: a Cognito-style bearer JWT on a v1 REST API request also triggers the region scan (uses a real RegionResolver, not a mock, to exercise the actual header-parsing logic).
  • Verified by reverting the fix: 2 of the 3 new tests fail (the third, exact-case-still-works style regression guard, isn't expected to distinguish old vs. new behavior).
  • Full apigateway test suite (319 tests) passes.

…PIs do

Unsigned requests (and requests carrying a non-SigV4 Authorization header,
e.g. a Cognito bearer JWT) resolve to RegionResolver's configured default
region rather than a region the caller specified. For v1 REST APIs,
resolveRestApiRegion already falls back to scanning all regions for the
apiId when that happens. HTTP API (v2) dispatch had no equivalent, so any
HTTP API deployed outside the default region returned 404 "Invalid API id
specified" for every unsigned or bearer-token-authenticated request - which
is effectively every request a browser, curl, or non-SigV4 client sends.

Adds ApiGatewayV2Service#resolveHttpApiRegion, mirroring
ApiGatewayService#resolveRestApiRegion exactly (same region::apiId key
shape), and RegionResolver#isRegionUnresolved to give dispatch() a single
correct signal for "region resolution silently fell back to the default"
that covers both the blank-header and non-SigV4-header cases the previous
blank-check missed.
…4 fallback

Adds unit coverage for the dispatch() region-resolution fix:

- An unsigned request for a v2 HTTP API deployed outside the default region
  must fall back to resolveHttpApiRegion and find it there.
- A correctly-resolved (signed) request must not pay for the fallback scan.
- A non-SigV4 Authorization header (e.g. a Cognito bearer JWT) on a v1 REST
  API must also trigger the region scan, not just a blank/missing header —
  using a real RegionResolver rather than a mock so the test exercises the
  actual header-parsing logic in isRegionUnresolved.

Verified each test fails when the corresponding fix is reverted: the v2 test
and the bearer-JWT test both fail (2 of 12) when dispatch()'s region-fallback
logic is rolled back to the pre-fix version, confirming they aren't
vacuously passing.
@greptile-apps

greptile-apps Bot commented Aug 6, 2026

Copy link
Copy Markdown

Greptile Summary

The PR aligns HTTP API region resolution with the existing REST API fallback for requests whose region cannot be derived from SigV4 credentials.

  • Adds a shared unresolved-region signal for unsigned and non-SigV4 authorization headers.
  • Adds cross-region HTTP API lookup and uses its result during v2 dispatch.
  • Extends REST API fallback to bearer-token requests and adds regression coverage.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
src/main/java/io/github/hectorvent/floci/core/common/RegionResolver.java Adds a region-resolution status check using the same SigV4 credential pattern as region extraction.
src/main/java/io/github/hectorvent/floci/services/apigateway/ApiGatewayExecuteController.java Applies unresolved-region fallback before HTTP API dispatch and broadens the existing REST API fallback to non-SigV4 authorization headers.
src/main/java/io/github/hectorvent/floci/services/apigatewayv2/ApiGatewayV2Service.java Adds account-scoped HTTP API region lookup by stored API key.
src/test/java/io/github/hectorvent/floci/services/apigateway/ApiGatewayExecuteControllerTest.java Covers unsigned cross-region HTTP API dispatch, resolved-region fast paths, and bearer-token REST API fallback.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Execute API request] --> B[Resolve region from Authorization]
    B --> C{Region unresolved?}
    C -->|No| D[Check HTTP API in resolved region]
    C -->|Yes| E[Scan HTTP APIs by API ID]
    E --> D
    D --> F{HTTP API found?}
    F -->|Yes| G[Dispatch HTTP API using selected region]
    F -->|No| H{Region unresolved?}
    H -->|Yes| I[Scan REST APIs by API ID]
    H -->|No| J[Use resolved region]
    I --> K[Dispatch REST API]
    J --> K
Loading

Reviews (2): Last reviewed commit: "chore: trigger CI" | Re-trigger Greptile

@rogueserenity

Copy link
Copy Markdown
Contributor Author

@hectorvent can you approve CI on this please?

@hectorvent

Copy link
Copy Markdown
Collaborator

@rogueserenity there are some incidents open https://www.githubstatus.com/.

@rogueserenity

Copy link
Copy Markdown
Contributor Author

@rogueserenity there are some incidents open https://www.githubstatus.com/.

I just saw that. Thanks for the heads up.

@hectorvent hectorvent added bug Something isn't working apigatewayv2 Amazon API Gateway v2 (HTTP/WebSocket) labels Aug 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

apigatewayv2 Amazon API Gateway v2 (HTTP/WebSocket) bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants