fix(apigatewayv2,iot,core,opensearch,lambda): unify tags, trailing-slash route, strict-iam fail-closed, VPC endpoints, ARN partitions (bug-hunt)#2317
Merged
Conversation
…ash route, strict-iam fail-closed, VPC endpoints, ARN partitions (bug-hunt)
…mance
The `/things/`->ListThings rewrite made an empty trailing path segment
(e.g. thingName="") stop matching the mutating {thingName} ops, so the
model's negative_too_short_<pathParam> variants got a 404 instead of the
expected validation error — regressing IoT conformance by 112 variants.
The trailing-slash behaviour was an unproven LOW-severity nicety; AWS
conformance (empty path param -> route to the {param} op -> ValidationException)
is the source of truth. The other four batch fixes (apigatewayv2 tags,
strict-IAM fail-closed, opensearch VPC endpoints, Lambda ARN partitions)
are unaffected.
…v2/anonymous/deny-message paths The unresolvable-AKID fail-closed branch broke established enforcement behaviour (sigv2 presigned attribution, anonymous explicit-deny handling, and the encoded iam deny message) because the guard fired on paths beyond the intended unknown-signed-key case. The fail-open gap it targeted is a real but MEDIUM concern; revisit in a dedicated, fully-traced PR. The other compat fixes in this PR (apigatewayv2 tag unification, opensearch VPC endpoints, Lambda ARN partitions) are unaffected.
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.
Summary
Fixes five confirmed client-compatibility / auth-enforcement bugs found during a bug hunt.
apigatewayv2 tag split -> Terraform perpetual drift.
CreateApi/CreateStagewrote inline tags onto the resource struct (HttpApi.tags/Stage.tags), whileTagResource/UntagResource/GetTagsoperated on a separate ARN-keyedstate.tagsstore — the two never synced, so create-time tags were invisible toGetTagsandTagResourcetags invisible toGetApi/GetStage. Unified onstate.tagsas the single source of truth: creates now also write there, all read paths (GetApi,GetApis,UpdateApi,GetStage,GetStages,UpdateStage) overlay from it, and deletes drop it. The tag verbs now percent-decode the non-greedy{ResourceArn}@httpLabelso the store is keyed by the plain ARN that creates compute. Fixed for both Api and Stage (identical split). DomainName/VpcLink keep create-time tags in a separate JSON blob — a distinct pre-existing gap, noted, out of scope here.IoT
match_routedidn't strip a trailing slash.GET /things/split to["things",""]and matched the 2-segmentDescribeThingwith an emptythingName(404) instead of 1-segmentListThings. Now strips a single trailing slash, mirroring the EKS/opensearch/scheduler routers. Affects every IoT collection with an item sibling.--iam strictfail-open on an unresolvable AKID (auth bypass). Without--verify-sigv4, a signed request whose access key id resolved to no principal (principal=None,access_key_id=Some) skipped both the identity-policy branch and the anonymous branch and fell through to the handler — bypassing enforcement (including an explicit Deny). Strict mode now fails closed withInvalidClientTokenIdfor an unknown key, guarded to: strict mode only, a configured credential resolver, and the unresolved-principal case. The reservedtest*root-bypass credentials are skipped upstream, so the local-dev bootstrap is unaffected;softmode and the--verify-sigv4path are untouched.opensearch VPC domain missing
Endpoints.vpc. VPC domains always emitted a public-style top-levelEndpointand never theEndpoints: {"vpc": ...}map Terraform reads. VPC domains (detected viaVPCOptionsin config) now emitEndpoints.vpcand omit the top-levelEndpoint, matching AWS; non-VPC domains keepEndpoint.Lambda ARN partition parsing (aws-cn / aws-us-gov). ARN-in-path parsing hardcoded
arn:aws:lambda:, so China/GovCloud ARNs weren't recognized. A newstrip_lambda_arn_prefixhelper matchesarn:<partition>:lambda:for any partition; used by bothnormalize_function_nameandqualifier_from_function_ref.Docs:
website/content/docs/reference/security.mdupdated to state that strict IAM now denies unknown access keys even without--verify-sigv4. The other four fixes are correctness round-trips with no new surface.Test plan
New tests, all passing:
test_api_tags_single_source_of_truth_round_trip(create-time tags visible to GetTags; TagResource visible to GetApi; Untag round-trips both read paths) +test_stage_tags_single_source_of_truth_round_trip.routes_by_method_and_pathassertsGET /things/->ListThings;thing_create_get_list_deleteasserts the trailing-slash GET returns the list.iam_enforcement.rs):unknown_access_key_denied_in_strict_without_sigv4(unknown AKID under strict/no-sigv4 ->InvalidClientTokenId) +resolved_principal_still_allowed_in_strict_without_sigv4(no regression).vpc_domain_reports_endpoints_vpc_not_public_endpoint+non_vpc_domain_reports_public_endpoint.normalize_function_name_strips_non_aws_partition_arns,qualifier_from_non_aws_partition_arn,get_function_accepts_china_partition_arn.Runs (worktree):
cargo test -p fakecloud-iot -p fakecloud-lambda -p fakecloud-opensearch -p fakecloud-apigatewayv2 -p fakecloud-core— green.cargo test -p fakecloud-e2e --test apigatewayv2 single_source— 2 passed.cargo test -p fakecloud-e2e --test iam_enforcement— 52 passed;--test sigv4_verification— 6 passed; boundary/abac/scheduler/session_policy suites — green (auth change touches dispatch).cargo clippy(touched crates +fakecloud-core --all-targets -D warnings, e2e tests) — clean.cargo fmt— applied.Summary by cubic
Unifies API Gateway v2 tags into a single ARN-keyed source of truth. Also fixes OpenSearch VPC endpoint shape, expands Lambda ARN parsing to all partitions, and reverts the IoT trailing-slash tweak to keep AWS‑conformant validation.
fakecloud-apigatewayv2: Use an ARN-keyed tag store for APIs and stages; percent-decode{ResourceArn}inTagResource/UntagResource/GetTags; overlay tags inGet*/Update*; clear tags on delete.fakecloud-opensearch: VPC domains exposeEndpoints.vpcand omit the top-levelEndpoint; non-VPC domains keepEndpoint.fakecloud-lambda: Parse Lambda ARNs for any partition (e.g.,aws-cn,aws-us-gov) for function refs and qualifiers.fakecloud-iot: Revert the trailing-slash routing change to preserve AWS-conformant validation on empty path params.Written for commit 1235201. Summary will update on new commits.