Skip to content

fix(cloudformation): provision AWS::ApiGatewayV2::Authorizer and wire Route.AuthorizerId - #1760

Merged
hectorvent merged 9 commits into
floci-io:mainfrom
rogueserenity:fix/apigatewayv2-authorizer-cfn
Aug 6, 2026
Merged

hectorvent merged 9 commits into
floci-io:mainfrom
rogueserenity:fix/apigatewayv2-authorizer-cfn

Conversation

@rogueserenity

Copy link
Copy Markdown
Contributor

Summary

Fixes #1758.

CloudFormationResourceProvisioner had no case for AWS::ApiGatewayV2::Authorizer (only AWS::ApiGateway::Authorizer, the v1/REST type, added in #796 for #788). The v2 resource fell through the default branch and was never provisioned — apiGatewayV2Service.createAuthorizer was never called, so apigatewayv2 get-authorizers came back empty regardless of what the template declared. provisionApiGatewayV2Route also never read AuthorizerId off the template at all, even though ApiGatewayV2Service.createRoute/updateRoute already handle it. Net effect: a CloudFormation-managed HTTP API v2 JWT authorizer silently degraded to AuthorizationType: NONE in practice — a route configured with AuthorizationType: JWT and a real AuthorizerId still let every request through unauthenticated, because neither the authorizer nor the route's link to it were ever persisted.

What changed

  • New case "AWS::ApiGatewayV2::Authorizer" in CloudFormationResourceProvisioner, plus provisionApiGatewayV2Authorizer, modeled on the neighboring provisionApiGatewayV2Route/Integration/Stage methods. Maps the CFN PascalCase properties (Name, AuthorizerType, IdentitySource, JwtConfiguration.Audience/Issuer, AuthorizerUri, AuthorizerPayloadFormatVersion, AuthorizerResultTtlInSeconds, EnableSimpleResponses) onto the existing ApiGatewayV2Service.createAuthorizer/updateAuthorizer camelCase request shape.
  • provisionApiGatewayV2Route now reads AuthorizerId from the template and passes it through, so a route's Ref to an authorizer resource actually resolves to something and gets persisted.
  • No delete case was added for AWS::ApiGatewayV2::Authorizer — consistent with the existing v2 Route/Integration/Stage types, none of which have a case in delete(...) either, since that method's signature (resourceType, physicalId, region) has no apiId to scope the lookup.

Test plan

  • New integration test createStack_apiGatewayV2AuthorizerIsProvisionedAndWiredToRoute in CloudFormationIntegrationTest: deploys a template with an AWS::ApiGatewayV2::Api + Authorizer + Integration + Route (AuthorizerId: !Ref Authorizer), then asserts GetAuthorizers returns the authorizer with the right JwtConfiguration, and GetRoutes shows the route's AuthorizerId resolved to that authorizer's real id.
  • Ran the full CloudFormationIntegrationTest suite (90 tests) plus RouteAuthorizerIdResponseTest and IntegrationConnectionTypeAndAuthorizerSimpleResponsesTest (the existing v2 authorizer/route regression coverage) — 100/100 pass, no regressions.
  • Also manually reproduced the bug against floci/floci:latest (1.5.30) via docker run + the AWS CLI before writing the fix, confirming get-authorizers returned {"Items":[]} and an unauthenticated request to the route returned 200 instead of 401.

… Route.AuthorizerId

CloudFormationResourceProvisioner had no case for AWS::ApiGatewayV2::Authorizer,
so the resource fell through the default stub branch and never reached
ApiGatewayV2Service — the same failure mode floci-io#788/floci-io#796 fixed for the v1
AWS::ApiGateway::Authorizer type. Stacks reported CREATE_COMPLETE, but
apigatewayv2 get-authorizers came back empty and routes referencing the
authorizer carried no authorizerId, so a JWT-authorized route silently
served every request unauthenticated.

Adds provisionApiGatewayV2Authorizer, modeled on the neighboring v2
Route/Integration/Stage provisioners, mapping the CFN PascalCase properties
(Name, AuthorizerType, IdentitySource, JwtConfiguration, AuthorizerUri,
AuthorizerPayloadFormatVersion, AuthorizerResultTtlInSeconds,
EnableSimpleResponses) onto the existing ApiGatewayV2Service.createAuthorizer
camelCase request shape. Also fixes provisionApiGatewayV2Route, which built
its request map without reading AuthorizerId at all even though
ApiGatewayV2Service.createRoute/updateRoute already handle it.

Fixes floci-io#1758.
@greptile-apps

greptile-apps Bot commented Jul 7, 2026

Copy link
Copy Markdown

Greptile Summary

This PR closes #1758 by wiring AWS::ApiGatewayV2::Authorizer into the CloudFormation provisioner (create/update/delete), fixing the missing AuthorizerId on provisionApiGatewayV2Route, and adding $request.querystring.* identity-source support to the JWT enforcement path. All three changes are necessary together: without the provisioner case the authorizer was never created; without the route fix the link was never persisted; without the querystring path any authorizer configured that way would still 401.

  • CloudFormationResourceProvisioner: adds provisionApiGatewayV2Authorizer (maps all CFN PascalCase properties onto the service's camelCase request, handles scalar or array IdentitySource), a scoped delete(StackResource, region) case that reads ApiId from stored attributes, and passes authorizerId through in provisionApiGatewayV2Route.
  • ApiGatewayExecuteController: extends extractToken / enforceJwtAuthorizer to accept UriInfo and extract tokens from $request.querystring.* sources, alongside the existing $request.header.* path.
  • Tests: four new CloudFormationIntegrationTest cases (provision + GetAtt wiring + scalar IdentitySource + delete) and a new HttpApiJwtAuthorizerQuerystringTest unit covering the querystring token extraction path.

Confidence Score: 5/5

Safe to merge — all three changed code paths (authorizer provisioning, route wiring, querystring token extraction) are narrow, well-tested, and consistent with existing patterns.

The provisioner additions follow the same shape as the neighbouring Route/Integration/Stage methods; the delete case stores and reads ApiId through the existing attribute map; the resolveIdentitySource helper correctly handles the scalar-vs-array CFN ambiguity that broke things before; and the querystring extraction in ApiGatewayExecuteController is a straightforward extension of the header path. Both concerns from the previous review round are addressed.

Files Needing Attention: No files require special attention.

Important Files Changed

Filename Overview
src/main/java/io/github/hectorvent/floci/services/cloudformation/CloudFormationResourceProvisioner.java Core fix: adds provision/delete cases for AWS::ApiGatewayV2::Authorizer and wires AuthorizerId into the Route provisioner; the new resolveIdentitySource helper correctly handles both scalar and array CFN forms.
src/main/java/io/github/hectorvent/floci/services/apigateway/ApiGatewayExecuteController.java Extends JWT enforcement to support $request.querystring.* identity sources by threading UriInfo through enforceJwtAuthorizer and extractToken; change is minimal and consistent with the existing header path.
src/test/java/io/github/hectorvent/floci/services/cloudformation/CloudFormationIntegrationTest.java Adds four integration tests covering authorizer provisioning, Ref and Fn::GetAtt wiring, scalar IdentitySource, and scoped delete against an out-of-band API; IdentitySource is now asserted in GetAuthorizers responses.
src/test/java/io/github/hectorvent/floci/services/apigatewayv2/HttpApiJwtAuthorizerQuerystringTest.java New regression test for querystring-based JWT token extraction; validates that a valid token in the query string is accepted (502, not 401), a missing token is rejected (401), and a header-only token does not satisfy a querystring identity source.

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

…horizer

resolveStringListOrEmpty silently returned an empty list when a template
supplied IdentitySource as a bare scalar string rather than the documented
array form, dropping the identity source instead of persisting it.
ApiGatewayV2Service.createAuthorizer/updateAuthorizer already accept a
scalar string for identitySource (identitySourceRaw instanceof String), so
the CFN provisioner was stricter than the service it calls.

Adds resolveIdentitySource, a local resolver that accepts both a scalar
string and an array. Adds a regression test asserting the scalar form is
persisted, alongside strengthening the existing test to assert
IdentitySource itself (previously unchecked).

Addresses review feedback on floci-io#1760.
rogueserenity added a commit to rogueserenity/floci that referenced this pull request Jul 7, 2026
…horizer

resolveStringListOrEmpty silently returned an empty list when a template
supplied IdentitySource as a bare scalar string rather than the documented
array form, dropping the identity source instead of persisting it.
ApiGatewayV2Service.createAuthorizer/updateAuthorizer already accept a
scalar string for identitySource (identitySourceRaw instanceof String), so
the CFN provisioner was stricter than the service it calls.

Adds resolveIdentitySource, a local resolver that accepts both a scalar
string and an array. Adds a regression test asserting the scalar form is
persisted, alongside strengthening the existing test to assert
IdentitySource itself (previously unchecked).

Addresses review feedback on floci-io#1760.
@rogueserenity

Copy link
Copy Markdown
Contributor Author

Good catch — fixed in f252ba5.

resolveStringListOrEmpty silently returned an empty list for a scalar-string IdentitySource, which is stricter than ApiGatewayV2Service.createAuthorizer/updateAuthorizer themselves (they already accept identitySourceRaw instanceof String). Added a local resolveIdentitySource that accepts both forms, matching the service layer, plus a regression test for the scalar case and a stronger assertion on the existing test (it wasn't checking IdentitySource at all before).

One correction on the framing: the AWS docs for AWS::ApiGatewayV2::Authorizer.IdentitySource list the type as "Array of String" and the only example uses array syntax — so the array form is the documented one, not the scalar. The bug is real regardless (the service layer's own leniency should carry through), just wanted to flag that for the record.

@rogueserenity

Copy link
Copy Markdown
Contributor Author

@hectorvent can you approve this one for CI? I have a follow up to this one once it merges to fix the SAM side of this.

@rogueserenity

Copy link
Copy Markdown
Contributor Author

@hectorvent ready for you to review/merge as you have time. Thanks!

} else {
authorizer = apiGatewayV2Service.updateAuthorizer(region, apiId, r.getPhysicalId(), req);
}
r.setPhysicalId(authorizer.getAuthorizerId());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rogueserenity thanks for building out the CloudFormation support here. Could we put AuthorizerId in the resource attributes as well as the physical ID? Ref works, but Fn::GetAtt Authorizer.AuthorizerId does not, so route templates receive the literal string and fail later. A small GetAtt route case would cover it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in def4f3b — provisionApiGatewayV2Authorizer now also stores r.getAttributes().put("AuthorizerId", authorizer.getAuthorizerId()) alongside the physical id, following the same pattern every other resource type already uses (S3, SQS, VPC, etc.) to make GetAtt resolvable. Fn::GetAtt Authorizer.AuthorizerId reads that attributes map, which was never populated before — only Ref (which reads the physical id) worked.

Added createStack_apiGatewayV2RouteResolvesAuthorizerIdViaGetAtt, a variant of the existing wired-route test that uses Fn::GetAtt instead of Ref for the route's AuthorizerId, asserting it resolves to the real id rather than the literal placeholder string. Verified the test actually catches the regression by temporarily removing the attribute and confirming it fails.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding that and for the regression coverage. Fn::GetAtt should work properly now.

Map<String, Object> req = new HashMap<>();
req.put("name", resolveOptional(props, "Name", engine));
req.put("authorizerType", resolveOptional(props, "AuthorizerType", engine));
req.put("identitySource", resolveIdentitySource(props, "IdentitySource", engine));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One runtime follow-up: HTTP API JWT authorizers support $request.querystring.* sources too, but the runtime only passes header information into token extraction. A template using a query-string token will 401 even with a valid JWT. Could we pass query parameters through and add a quick execution-level test?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 34d238b — extractToken only ever received HttpHeaders, with no query-parameter access at all, so any IdentitySource like $request.querystring.token was silently unusable and a request using it always 401'd. Threaded UriInfo through enforceJwtAuthorizer/extractToken (it was already available one call site up, in dispatchV2) and added a $request.querystring. branch mirroring the one enforceRequestAuthorizerV2 already has for Lambda REQUEST authorizers.

Added HttpApiJwtAuthorizerQuerystringTest — an execution-level test hitting a real JWT-protected route with the token only in the query string (asserting it gets past authorization), plus checks that a request with no token anywhere 401s, and that a token in the Authorization header alone doesn't satisfy an authorizer configured for a querystring-only identity source. Verified the primary case fails without the fix.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, thanks for wiring that through the execution path and adding the test. This handles the query-string JWT case I was concerned about.

case "AWS::ApiGateway::Deployment" -> provisionApiGatewayDeployment(resource, properties, engine, region);
case "AWS::ApiGateway::Stage" -> provisionApiGatewayStage(resource, properties, engine, region);
case "AWS::ApiGatewayV2::Api" -> provisionApiGatewayV2Api(resource, properties, engine, region, accountId, stackName);
case "AWS::ApiGatewayV2::Authorizer" -> provisionApiGatewayV2Authorizer(resource, properties, engine, region);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One cleanup detail: the generic delete path does not know about this resource. If ApiId comes from a parameter rather than a stack-owned API, deleting the stack reports success but leaves the authorizer behind. Could we retain the API ID on the resource and add a scoped delete path for it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in def4f3b — added a scoped case for AWS::ApiGatewayV2::Authorizer in delete(StackResource, region), following the same shape already used for AWS::EKS::Nodegroup (a resource needing more context than type+physicalId to delete). ApiId is now stored as a resource attribute during provisioning and read back here to call apiGatewayV2Service.deleteAuthorizer(region, apiId, physicalId) directly — previously the generic type/physicalId switch had no case for this type at all and silently no-op'd.

Added deleteStack_apiGatewayV2AuthorizerOnNonStackOwnedApiIsRemoved, which deliberately creates the API out-of-band (not as a stack resource) so AWS::ApiGatewayV2::Api's own cascading delete can't be the thing removing the authorizer — that's exactly the scenario you flagged, and it isolates the new scoped delete path as the only thing that could make the test pass. Verified it fails without the fix.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for tracking the API ID and covering the external API case. This looks right now.

…te for AWS::ApiGatewayV2::Authorizer

- Fn::GetAtt Authorizer.AuthorizerId now resolves: provisionApiGatewayV2Authorizer
  only set the physical id, never the resource's attributes map, so GetAtt (which
  reads a separate map from Ref) fell back to a literal placeholder string.

- Stack deletion now actually removes the authorizer: the generic type/physicalId
  delete switch had no case for AWS::ApiGatewayV2::Authorizer at all and silently
  no-op'd. Added a scoped case in delete(StackResource, region) following the same
  shape already used for AWS::EKS::Nodegroup (a resource needing extra context
  beyond type+physicalId, stored as an attribute during provisioning).

Both fixes store ApiId as a resource attribute during provisioning, since it's
needed by the new delete path and wasn't previously retained anywhere.
…JWT authorizers

extractToken only checked HttpHeaders — it had no query-parameter access at all, so
any IdentitySource entry like $request.querystring.token was silently unusable, and
a request using a valid token there always 401'd. Threads UriInfo through
enforceJwtAuthorizer/extractToken and adds a $request.querystring. branch mirroring
the one enforceRequestAuthorizerV2 already has for Lambda REQUEST authorizers.
…thorizer-cfn

# Conflicts:
#	src/test/java/io/github/hectorvent/floci/services/cloudformation/CloudFormationIntegrationTest.java
…thorizer-cfn

# Conflicts:
#	src/main/java/io/github/hectorvent/floci/services/cloudformation/CloudFormationResourceProvisioner.java
@hectorvent

Copy link
Copy Markdown
Collaborator

Hello @rogueserenity,

Thanks for the PR!

Could you please update the commit history to remove the Co-authored-by: Claude <...> line from the commit message? We prefer to keep the attribution focused on human contributors for this project. Once that's cleaned up, I'm happy to take another look!

@hectorvent hectorvent added the waiting-contributor Deprecated: use waiting-author label Aug 1, 2026
@rogueserenity
rogueserenity force-pushed the fix/apigatewayv2-authorizer-cfn branch from 08106bb to e9b3553 Compare August 1, 2026 21:21
@rogueserenity

Copy link
Copy Markdown
Contributor Author

Done — history rewritten in e9b3553 to drop the Co-Authored-By: Claude ... trailers. Sorry about that.

Only the two commits that carried it were touched (34d238b05939b6f1 and def4f3b6fda5cfce); the rest were unchanged apart from new SHAs from the rewrite. Merge topology is preserved and the tree is byte-identical to what you last reviewed — git diff against the old head is empty, so nothing about the change itself moved.

Audit for the record:

git log --pretty='%(trailers:key=Co-Authored-By,valueonly)' upstream/main..HEAD

comes back empty across all 7 commits. CI is re-running now.

@rogueserenity

Copy link
Copy Markdown
Contributor Author

@hectorvent this is ready for you to merge

// the authorizer id) — same shape as the Nodegroup case above. Without this, the generic
// type/physicalId delete path has no case for this type at all and silently no-ops,
// leaving the authorizer behind in AWS after the stack reports deleted.
if ("AWS::ApiGatewayV2::Authorizer".equals(resourceType)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heads up before this gets merged — GitHub reports the branch as conflicting with main (mergeable: CONFLICTING, mergeStateStatus: DIRTY), so it can't go in as-is despite the green checks.

Exactly one file collides, and it's right here. main has since gained an AWS::Events::Rule case in delete(StackResource, region) in the same spot this PR adds its AWS::ApiGatewayV2::Authorizer case — both immediately after the AWS::EKS::Nodegroup block, and both ending on the same shared return; } lines, which is what makes git treat it as a conflict rather than two independent insertions.

The resolution is to keep both blocks, each closing with its own return;:

if ("AWS::Events::Rule".equals(resourceType)) {
    deleteEventBridgeRuleSafe(resource.getPhysicalId(),
            resource.getAttributes().get("EventBusName"), region);
    return;
}
if ("AWS::ApiGatewayV2::Authorizer".equals(resourceType)) {
    String apiId = resource.getAttributes().get("ApiId");
    ...
    return;
}

Worth resolving deliberately rather than by reflex: because that trailing return; } is shared context, taking either side wholesale still compiles and CI still goes green — it just silently drops the other side's delete path, either main's custom-bus rule cleanup or the authorizer cleanup this PR exists to add. That failure is invisible until a stack delete leaves something behind.

I checked the rest of the merge and nothing else collides: resolveOptional, resolveStringListOrEmpty, and the createAuthorizer / updateAuthorizer / deleteAuthorizer signatures are all unchanged on main, so no other fixups should be needed after resolving this hunk.

The three things I raised earlier — the AuthorizerId attribute, the $request.querystring.* identity source, and this scoped delete — all look right at e9b35533.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Conflict resolved. Ready for merge.

…thorizer-cfn

# Conflicts:
#	src/main/java/io/github/hectorvent/floci/services/cloudformation/CloudFormationResourceProvisioner.java
The Build and Test job failed on a single flaky error in
RuntimeApiServerTest.extensionRegister_racedAgainstStop_eventuallyDeliversShutdown
(EOFException on an HTTP/2 read while racing extension registration against
server stop) — 1 of 8325 tests. This branch changes no Lambda code; that test
is from floci-io#1773 and lives on main independently. Passes locally on repeat runs.

@hectorvent hectorvent left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hectorvent
hectorvent merged commit 7f51c74 into floci-io:main Aug 6, 2026
13 checks passed
@hectorvent

Copy link
Copy Markdown
Collaborator

🎉 This PR is included in version 1.6.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

abanna pushed a commit to abanna/floci that referenced this pull request Aug 6, 2026
# [1.6.0](floci-io/floci@1.5.34...1.6.0) (2026-08-06)

### Bug Fixes

* **1790:** better populate describe alarm responses ([floci-io#1792](floci-io#1792)) ([fcb22be](floci-io@fcb22be))
* **apigateway:** fall through to less specific resources on method mi… ([floci-io#1630](floci-io#1630)) ([96c7aa6](floci-io@96c7aa6)), closes [floci-io#1547](floci-io#1547)
* **apigateway:** import authorizers and security requirements from OpenAPI ([floci-io#1798](floci-io#1798)) ([91e06eb](floci-io@91e06eb))
* **apigateway:** use last duplicate header value ([floci-io#1806](floci-io#1806)) ([6a214e8](floci-io@6a214e8))
* **athena:** report the result CSV object key as OutputLocation ([floci-io#1895](floci-io#1895)) ([418ec1b](floci-io@418ec1b)), closes [floci-io#1752](floci-io#1752)
* **cloudformation:** AWS::IAM::ManagedPolicy exposes PolicyArn for Fn::GetAtt ([floci-io#2056](floci-io#2056)) ([f719033](floci-io@f719033))
* **cloudformation:** keep uniqueness suffix when truncating generated resource names ([floci-io#1802](floci-io#1802)) ([48b2139](floci-io@48b2139)), closes [floci-io#1825](floci-io#1825)
* **cloudformation:** preserve subnet public IP setting ([floci-io#2031](floci-io#2031)) ([b62d1e7](floci-io@b62d1e7))
* **cloudformation:** provision AWS::ApiGatewayV2::Authorizer and wire Route.AuthorizerId ([floci-io#1760](floci-io#1760)) ([7f51c74](floci-io@7f51c74)), closes [floci-io#1773](floci-io#1773)
* **cloudformation:** resolve Fn::GetAtt [Vpc, DefaultSecurityGroup] ([floci-io#1977](floci-io#1977)) ([bdad066](floci-io@bdad066)), closes [floci-io#1976](floci-io#1976)
* **cloudformation:** treat delete of an already-removed DynamoDB table or Lambda function as idempotent ([floci-io#1803](floci-io#1803)) ([5cb26ff](floci-io@5cb26ff))
* **codebuild:** stabilize start and retry responses ([floci-io#2052](floci-io#2052)) ([fa96b79](floci-io@fa96b79))
* **cognito:** reject unconfirmed users in SRP auth ([floci-io#2027](floci-io#2027)) ([733c72d](floci-io@733c72d))
* **dockerfile:** ensure docker-java compatibility ([floci-io#2096](floci-io#2096)) ([7ade290](floci-io@7ade290))
* **dynamodb:** resolve nested document paths in ADD and DELETE update actions ([floci-io#1908](floci-io#1908)) ([c052259](floci-io@c052259))
* **ec2:** DescribeKeyPairs returns InvalidKeyPair.NotFound for missing names/ids ([floci-io#1932](floci-io#1932)) ([7d96106](floci-io@7d96106)), closes [floci-io#1911](floci-io#1911)
* **ec2:** return AWS-parity MissingParameter for CreateSubnet without VpcId ([floci-io#2094](floci-io#2094)) ([88408d8](floci-io@88408d8)), closes [floci-io#2089](floci-io#2089)
* **ecs:** resolve Secrets Manager JSON-key selectors in task definition secrets ([floci-io#2133](floci-io#2133)) ([e3c180b](floci-io@e3c180b)), closes [floci-io#1912](floci-io#1912)
* **lambda:** carry the owning account into published version snapshots ([floci-io#2041](floci-io#2041)) ([f4e8bd8](floci-io@f4e8bd8)), closes [floci-io#2040](floci-io#2040)
* **lambda:** report resolved executed version ([floci-io#2026](floci-io#2026)) ([2889fbd](floci-io@2889fbd))
* **lambda:** reset volatile DynamoDB Streams ESM checkpoints on restart ([floci-io#2077](floci-io#2077)) ([847c30a](floci-io@847c30a))
* **pipes:** register kafka-clients reflection metadata for native image ([floci-io#2068](floci-io#2068)) ([ab73379](floci-io@ab73379))
* **s3:** accept a percent-encoded bucket/key separator in copy sources ([floci-io#2060](floci-io#2060)) ([a8ed218](floci-io@a8ed218)), closes [floci-io#2038](floci-io#2038)
* **s3:** apply CreateBucketConfiguration tags on bucket creation ([floci-io#2115](floci-io#2115)) ([79031a2](floci-io@79031a2))
* **s3:** include EventBridgeConfiguration in GetBucketNotification response ([floci-io#2072](floci-io#2072)) ([b8edd37](floci-io@b8edd37))
* **s3:** recognize virtual-hosted-style requests over HTTP/2 ([floci-io#1954](floci-io#1954)) ([5f7d4d2](floci-io@5f7d4d2)), closes [floci-io#1866](floci-io#1866)
* **ssm:** report invalid batch parameter names ([floci-io#2075](floci-io#2075)) ([04873bf](floci-io@04873bf))
* **tls:** reuse the persisted self-signed certificate across restarts ([floci-io#1799](floci-io#1799)) ([a4356f2](floci-io@a4356f2))

### Features

* Add AWSCloudFormationReadOnlyAccess as a managed policy. ([floci-io#2057](floci-io#2057)) ([0142dc4](floci-io@0142dc4))
* **apigateway:** support floci:override-id for v1 and v2 ([floci-io#2045](floci-io#2045)) ([02385da](floci-io@02385da)), closes [floci-io#1593](floci-io#1593)
* **bedrock:** add proxy backend for real LLM responses via OpenAI-compatible API ([floci-io#1789](floci-io#1789)) ([875e0f2](floci-io@875e0f2))
* **cloudcontrol:** include EC2 resource tags ([floci-io#1933](floci-io#1933)) ([205a8f1](floci-io@205a8f1))
* **cloudformation:** provision AWS::EC2::LaunchTemplate ([floci-io#1973](floci-io#1973)) ([4e0a815](floci-io@4e0a815)), closes [floci-io#1971](floci-io#1971)
* **cloudformation:** provision AWS::EC2::VPCGatewayAttachment ([floci-io#1972](floci-io#1972)) ([1a99721](floci-io@1a99721)), closes [floci-io#1970](floci-io#1970)
* **cloudformation:** provision AWS::SecretsManager::SecretTargetAttachment ([floci-io#1804](floci-io#1804)) ([62a576c](floci-io@62a576c))
* **cloudformation:** support AWS::Events::EventBus and EventBusPolicy ([floci-io#1794](floci-io#1794)) ([76f602f](floci-io@76f602f))
* **cognito:** implement ResendConfirmationCode ([floci-io#2071](floci-io#2071)) ([bb7c45c](floci-io@bb7c45c)), closes [floci-io#2067](floci-io#2067)
* **ec2:** added attach and detach volume support ([floci-io#1787](floci-io#1787)) ([2c74329](floci-io@2c74329))
* **ec2:** return an empty set for DescribeVpnGateways ([floci-io#1975](floci-io#1975)) ([3baf4f4](floci-io@3baf4f4)), closes [floci-io#1974](floci-io#1974)
* **iam:** list entities attached to managed policies ([floci-io#1808](floci-io#1808)) ([78ba5b3](floci-io@78ba5b3))
* **iam:** seed Amazon Bedrock managed policies ([floci-io#2034](floci-io#2034)) ([5874348](floci-io@5874348)), closes [floci-io#1559](floci-io#1559) [floci-io#1216](floci-io#1216)
* **iam:** seed the managed policies CDK bootstrap and the scenario stacks attach ([floci-io#2064](floci-io#2064)) ([43aea09](floci-io@43aea09)), closes [floci-io#2059](floci-io#2059) [floci-io#2057](floci-io#2057) [floci-io#2057](floci-io#2057)
* **kms:** implement ListKeyPolicies ([floci-io#2046](floci-io#2046)) ([760115d](floci-io@760115d)), closes [floci-io#1528](floci-io#1528)
* **lambda:** implement the Lambda Extensions API ([floci-io#1773](floci-io#1773)) ([9f0dec9](floci-io@9f0dec9))
* **lambda:** support extra /etc/hosts entries on Lambda launch ([floci-io#2073](floci-io#2073)) ([b543aa4](floci-io@b543aa4))
* **mwaa:** add Amazon MWAA emulation backed by real Airflow (LocalExecutor) ([floci-io#2086](floci-io#2086)) ([7e4e3e8](floci-io@7e4e3e8))
* **release:** one-button release cut from main and ECR Public versioned publishing ([floci-io#2127](floci-io#2127)) ([61011c0](floci-io@61011c0))
* **rum:** add CloudWatch RUM app-monitor service ([floci-io#1797](floci-io#1797)) ([aadc93e](floci-io@aadc93e))
* **sqs:** retain MessageGroupId on standard queue messages ([floci-io#1891](floci-io#1891)) ([a01b707](floci-io@a01b707)), closes [floci-io#1496](floci-io#1496)

### Performance Improvements

* **docker:** stop duplicating the native binary into a second image layer ([floci-io#2069](floci-io#2069)) ([9e90e5c](floci-io@9e90e5c))
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 cloudformation AWS CloudFormation released waiting-contributor Deprecated: use waiting-author

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] CloudFormation drops AWS::ApiGatewayV2::Authorizer

3 participants