API Gateway Hosting Guide
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. SPDX-License-Identifier: MIT-0
API Gateway Hosting Guide
Section titled “API Gateway Hosting Guide”Overview
Section titled “Overview”The GenAI IDP Accelerator supports an alternative Web UI hosting mode that serves the React single-page application (SPA) directly from API Gateway, as an S3 proxy on the same REST API that already backs the UI’s data operations. This replaces CloudFront for environments that require VPC-based or private-network hosting.
Set WebUIHosting=APIGateway to enable it. The default remains CloudFront.
Note: For standard public deployments, CloudFront hosting (the default) is recommended. Use API Gateway hosting only when your environment has specific requirements that prevent using CloudFront.
Migrating from ALB hosting? Earlier releases offered an
ALBhosting option (an internal Application Load Balancer fronting an S3 VPC Interface Endpoint). That option has been removed and replaced by API Gateway hosting, which is simpler (no ALB, no S3 VPC endpoint, no ACM certificate) and reuses the REST API you already deploy. See Migrating from ALB hosting below.
When to Use API Gateway Hosting
Section titled “When to Use API Gateway Hosting”API Gateway hosting is designed for organizations that need the full IDP Web UI but cannot use CloudFront due to network or compliance constraints:
- Private network requirements — combine with
ApiGatewayVisibility=PRIVATEso the UI (and the API) is reachable only through a VPC interface endpoint. - Regulated / VPC-only environments — all traffic traverses private network paths; protect the API stage with the built-in WAFv2 IP allow-list.
- Corporate network restrictions — users reach the app exclusively over VPN or Direct Connect into the VPC.
- GovCloud-style constraints where CloudFront is unavailable but you still want the UI (contrast with Headless Deployment, which removes the UI entirely).
Architecture
Section titled “Architecture”Standard Hosting (CloudFront)
Section titled “Standard Hosting (CloudFront)”Internet Users → CloudFront (Edge) → S3 Origin (WebUI Bucket) ↘ (data) → API Gateway REST API → LambdaAPI Gateway Hosting
Section titled “API Gateway Hosting”Users → API Gateway REST API (stage: /api) ├── GET / → S3 proxy → WebUI bucket / index.html ├── GET /{proxy+} → S3 proxy → WebUI bucket / <key> └── POST /op/{field} → Lambda dispatcher (data operations, Cognito-authed)The Web UI and the data API are served from one origin and one stage, so:
- No CORS between the UI and the API (same origin).
- VPC support is inherited:
ApiGatewayVisibility=PRIVATEmakes both the UI and the API reachable only via the execute-api VPC interface endpoint. - WAF is inherited: the optional stage-level WAFv2 IP allow-list
(
WAFAllowedIPv4Ranges) covers the UI routes automatically. - No S3 VPC endpoint is required — API Gateway reaches the Web UI bucket over AWS-internal networking via an IAM role, not through a customer VPCE.
Security headers: The CloudFront distribution attaches a response-headers policy (HSTS, X-Content-Type-Options, a CSP, etc.). API Gateway hosting serves the S3 objects directly and does not add those headers. For most private/VPC-only deployments this is acceptable (access is already network- and WAF-restricted); if you need strict response headers on a public API Gateway deployment, front it with a custom domain + CloudFront, or add the headers via a gateway response / edge layer.
How the SPA is served
Section titled “How the SPA is served”- The static GET routes use
AuthorizationType: NONE(a browser fetching the SPA shell has no JWT yet); authentication happens inside the app when it callsPOST /op/{field}with a Cognito token. BinaryMediaTypes: */*is enabled so images/fonts/JS/CSS bytes pass through intact. The JSON data path is unaffected — the dispatcher base64-decodes request bodies.- The SPA uses HashRouter, so client-side routes live in the URL fragment
(
/api/#/...) and need no server-side rewrite — deep links are served byindex.htmlat/, and a genuinely nonexistent asset path returns 404 (the{proxy+}route maps each path to the matching S3 key; there is no rewrite-to-index.htmlbecause hash routing makes it unnecessary). - Because the API serves under the stage prefix
/api, the UI is built with Vitebase=/api/(CodeBuild setsVITE_UI_BASE_PATH=/api/automatically in this mode), so every asset URL resolves under/api/.
Configuration
Section titled “Configuration”Minimum (public/regional API Gateway hosting, no VPC):
WebUIHosting=APIGatewayPrivate / VPC-only hosting (recommended for the network-restricted use case):
WebUIHosting=APIGatewayApiGatewayVisibility=PRIVATEDeployInVPC=trueVpcId=vpc-xxxxxxxxPrivateSubnetIds=subnet-aaa,subnet-bbbLambdaSubnetIds=subnet-aaa,subnet-bbbLambdaSecurityGroupId=sg-xxxxxxxxApiGatewayVpcEndpointId=vpce-xxxxxxxx # execute-api interface endpointOptional WAF IP allow-list (applies to the whole stage — UI + API):
WAFAllowedIPv4Ranges=203.0.113.0/24,198.51.100.0/24
ApiGatewayVisibility=PRIVATErequiresDeployInVPC=trueand an existing execute-api VPC interface endpoint (with private DNS enabled) so the regionalexecute-apihostname resolves inside the VPC. All Lambdas run in the VPC in this mode.
Prerequisites (PRIVATE / VPC mode)
Section titled “Prerequisites (PRIVATE / VPC mode)”You need an existing VPC providing:
- At least 2 private subnets in different AZs for the Lambdas.
- Egress to AWS services — either a NAT gateway or the full set of VPC interface endpoints (Bedrock, Textract, S3, DynamoDB, SQS, Step Functions, etc.). See Private Network Deployment.
- An
execute-apiinterface endpoint withPrivateDnsEnabled: true, passed asApiGatewayVpcEndpointId. - A Lambda security group allowing outbound HTTPS, passed as
LambdaSecurityGroupId. - DNS resolution enabled (
enableDnsSupport+enableDnsHostnames).
A ready-made, self-contained test VPC (NAT egress + one execute-api endpoint) is
provided at scripts/sdlc/apigw-hosting-test-vpc.yaml and is used by the CI
deployment test.
OAuth / Cognito callbacks
Section titled “OAuth / Cognito callbacks”The UI URL in API Gateway mode is an output of the API resolvers nested stack,
which is created after the Cognito user-pool client. To avoid a circular
CloudFormation dependency, the stack registers the API Gateway callback / logout
URLs on the Cognito client via a post-deploy custom resource
(WebUIClientOAuthUrls) rather than declaring them inline. This is transparent —
no action is required — but note that if you use an External IdP, the OAuth
redirect URL is https://<api-id>.execute-api.<region>.amazonaws.com/api/.
If you front the app with a custom domain, set CustomDomainUrl; the Web UI
then uses window.location.origin for OAuth redirects so both the API Gateway
URL and the custom domain work.
Accessing the UI
Section titled “Accessing the UI”The application URL is the ApplicationWebURL stack output, e.g.
https://<api-id>.execute-api.<region>.amazonaws.com/api/. In PRIVATE mode this
resolves only inside the VPC (via the execute-api endpoint) — reach it from a
VPN/Direct Connect client, a bastion, or a workstation in the VPC.
Migrating from ALB hosting
Section titled “Migrating from ALB hosting”If you previously deployed with WebUIHosting=ALB:
- The
ALB*parameters (ALBVpcId,ALBSubnetIds,ALBCertificateArn,ALBScheme,ALBAllowedCIDRs) have been removed. Remove them from your parameter file / deployment scripts. - Set
WebUIHosting=APIGateway. For the equivalent private-network posture, also setApiGatewayVisibility=PRIVATE,DeployInVPC=true, and provideVpcId/PrivateSubnetIds/LambdaSubnetIds/LambdaSecurityGroupId/ApiGatewayVpcEndpointId. - You no longer need an ACM certificate, an ALB, or an auto-provisioned S3 VPC
Interface Endpoint. (A BYO S3 endpoint for browser presigned-URL uploads
is still supported via
S3VpcEndpointIdOverride/S3VpcEndpointDnsNameOverride+S3PresignedUrlViaVpcEndpoint=true.) - The application URL changes from the ALB DNS name to the execute-api
/apiURL (seeApplicationWebURLoutput). Update any bookmarks / DNS aliases.
Troubleshooting
Section titled “Troubleshooting”- UI loads but assets 404: confirm the build ran with
VITE_UI_BASE_PATH=/api/(CodeBuild sets this automatically whenWebUIHosting=APIGateway). Asset URLs inindex.htmlmust start with/api/. - UI unreachable in PRIVATE mode: verify you are inside the VPC and the
execute-api endpoint has
PrivateDnsEnabled: true; check the endpoint SG allows 443 from your client. - 403 on the UI with WAF enabled: your client IP is not in
WAFAllowedIPv4Ranges. - OAuth redirect_mismatch with External IdP: confirm the
WebUIClientOAuthUrlscustom resource succeeded (CloudWatch logs) and the client’s callback URLs include the execute-api/api/URL.