Move WAF to a CloudFront front door; add optional Cognito inbound auth - #16
Open
arditti wants to merge 5 commits into
Open
Move WAF to a CloudFront front door; add optional Cognito inbound auth#16arditti wants to merge 5 commits into
arditti wants to merge 5 commits into
Conversation
- Remove the REGIONAL WAF Web ACL and its Gateway association - Add EdgeWafStack (us-east-1) with the same policy at CLOUDFRONT scope: ChatGPT/Claude IP allowlist, AWS managed rules, rate limiting - Add a CloudFront distribution in front of the Gateway (caching disabled, all-viewer-except-host origin request policy, HTTPS only) - Serve /.well-known/oauth-protected-resource from a CloudFront Function instead of the Lambda@Edge approach in the custom-domains guide - deploy.sh bootstraps us-east-1 when needed and deploys both stacks - verify.sh targets the CLOUDFRONT-scope IP set and also checks the default-deny behavior and the OAuth discovery rewrite
…e verify - Cognito machine-to-machine pool + resource server (mcp-gateway/invoke) + hosted domain + client_credentials app client; gateway inbound switches to GatewayAuthorizer.usingCognito, closing the direct-gateway WAF bypass - Auth mode is baked into the gateway logical ID/name: the service forbids in-place authorizer-type updates, so switching modes replaces the gateway (the CloudFront front-door URL stays stable) - CloudFront Function advertises the Cognito issuer in authorization_servers (placeholder substitution now replaces all occurrences, not just the first) - verify.sh: force IPv4 (CloudFront is dual-stack, allowlist is IPv4-only), fetch a Cognito token when present, assert 401 without a token, and check the discovery document carries the issuer - AGENTS.md: deploy/test runbook for agents, including the IPv6 and CLOUDFRONT-scope gotchas
…25-06-18 support - Gateway now advertises MCP protocol 2025-06-18 (modern stateless streamable HTTP) alongside 2025-03-26 — modern clients no longer have to fall back to legacy mode - get-token.sh: mint a Cognito client_credentials token from stack outputs - inspect.sh: launch MCP Inspector with IPv4-first DNS and the right endpoint/header printed (and on the clipboard on macOS) - README/AGENTS.md: document the interactive test flow
…Function, optional Cognito - AI hosts now enter through the CloudFront front door (/mcp); WAF protects the distribution instead of the Gateway - CloudFront Function note for the /.well-known OAuth discovery rewrite - Amazon Cognito shown as the optional -c auth=cognito JWT authorizer - Existing CloudFront relabeled as the Images CDN; drawio source updated and PNG re-exported
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
This PR moves edge protection off the AgentCore Gateway and onto a CloudFront distribution in front of it, following the Gateway custom-domains guide — but with a CloudFront Function instead of Lambda@Edge — and adds an optional Cognito JWT inbound authorizer.
CloudFront + WAF front door
EdgeWafStackat CLOUDFRONT scope, pinned to us-east-1 with CDK cross-region references, so the app still deploys to any AgentCore region.CACHING_DISABLED,ALL_VIEWER_EXCEPT_HOST_HEADER, HTTPS-only, HTTP/2+3) with the Web ACL attached.GatewayResourceUrlnow returns the CloudFront URL; the raw Gateway URL is exposed separately asGatewayDirectUrlwith a warning.domainNames+certificate).CloudFront Function instead of Lambda@Edge
The custom-domains guide suggests a Lambda@Edge ORIGIN_RESPONSE function to fix
/.well-known/oauth-protected-resourceadvertising the Gateway's own domain. A viewer-request CloudFront Function generates the discovery document directly at the edge from the Host header — correct for both the default cloudfront.net domain and any custom domain, cheaper and simpler than Lambda@Edge, and the request never reaches the Gateway.Optional Cognito inbound auth (
-c auth=cognito)mcp-gateway/invokescope, hosted domain, client_credentials app client) and switches the Gateway toGatewayAuthorizer.usingCognito.authorization_servers.Protocol + testing
2025-06-18(modern stateless streamable HTTP) alongside2025-03-26, so current clients no longer fall back to legacy mode.verify.shcovers the new architecture end to end: asserts WAF default-deny (403), allowlists the caller's IPv4, runsinitialize→tools/list→tools/call list_unicorns, checks the discovery document, asserts 401 without a token in Cognito mode, and cleans up after itself. All calls force IPv4 — CloudFront is dual-stack while the allowlist IP sets are IPv4-only, which silently 403s IPv6 clients otherwise.get-token.sh(mints a Cognito client_credentials token from stack outputs) andinspect.sh(launches MCP Inspector with IPv4-first DNS and the right endpoint/header).AGENTS.mddocuments the deploy/test fast path and the gotchas (IPv6, CLOUDFRONT-scope WAF API calls, edge propagation,<target>___<tool>naming).Testing performed
Deployed to a personal account in us-east-1 in both modes and ran
./verify.shend to end. Cognito mode, all checks green:Also verified interactively with MCP Inspector (streamable HTTP, modern 2025-06-18 protocol) and confirmed the direct Gateway URL returns 401 without a token in Cognito mode.
By submitting this pull request, I confirm that my contribution is made under the terms of the MIT-0 license.