Skip to content

Commit a708af6

Browse files
authored
fix(sts): do not inject region info for STS service with VPC endpoint hostname (#113)
AWS services can be used inside a private VPC without Internet access by creating private links(VPC endpoints). When creating VPC endpoint for an AWS service, the Enable private DNS name is enabled by default, which means that a private DNS record will be created whose value is just the same as the AWS service's public endpoint(for example, s3.amazonaws.com) but pointing at the private VPC endpoint. This is what is expected to be a common practice when using VPC endpoint to access AWS service. However, user can also disable it to not create this "fake" DNS record, and use the VPC endpoint hostname directly(something like vpce-abcdefghijklmn-abcdefg.sts.us-east-1.vpce.amazonaws.com). In this case, there is no need to inject region info into the endpoint domain since the hostname itself always contains the region for this VPC endpoint. We've encountered a case in which the user is using a VPC endpoint hostname directly for STS service and region info gets injected unexpectedly, thus STS service cannot be used. This PR fixes it. More information: https://docs.aws.amazon.com/vpc/latest/privatelink/privatelink-access-aws-services.html#interface-endpoint-dns-hostnames FTI-5934
1 parent 722045b commit a708af6

File tree

3 files changed

+42
-2
lines changed

3 files changed

+42
-2
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,8 @@ Release process:
182182
- feat: decode AWS api response json body with array metatable
183183
[114](https://github.com/Kong/lua-resty-aws/pull/114)
184184

185+
- fix: do not inject region info for sts service with VPC endpoint hostname
186+
[113](https://github.com/Kong/lua-resty-aws/pull/113)
185187

186188
### 1.4.1 (19-Apr-2024)
187189

spec/01-generic/02-aws_spec.lua

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,37 @@ describe("AWS main instance", function()
9292
assert.same("https://sts.eu-central-1.amazonaws.com", sts.config.endpoint)
9393
end)
9494

95+
it("do not inject sts region info for sts vpc endpoint url", function()
96+
local aws = AWS({
97+
region = "eu-central-1",
98+
stsRegionalEndpoints = "regional",
99+
})
100+
101+
aws.config.credentials = aws:Credentials {
102+
accessKeyId = "test_id",
103+
secretAccessKey = "test_key",
104+
}
105+
106+
assert.is.table(aws.config)
107+
108+
local regional_vpc_endpoint_url = "https://vpce-abcdefg-hijklmn-eu-central-1a.sts.eu-central-1.vpce.amazonaws.com"
109+
110+
local sts, _ = aws:STS({
111+
endpoint = regional_vpc_endpoint_url,
112+
})
113+
local _, _ = sts:assumeRole {
114+
RoleArn = "aws:arn::XXXXXXXXXXXXXXXXX:test123",
115+
RoleSessionName = "aws-test",
116+
}
117+
118+
assert.same(regional_vpc_endpoint_url, sts.config.endpoint)
119+
120+
local _, _ = sts:assumeRole {
121+
RoleArn = "aws:arn::XXXXXXXXXXXXXXXXX:test123",
122+
RoleSessionName = "aws-test",
123+
}
124+
assert.same(regional_vpc_endpoint_url, sts.config.endpoint)
125+
end)
126+
127+
95128
end)

src/resty/aws/init.lua

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ local execute_request = require("resty.aws.request.execute")
88
local split = require("pl.utils").split
99
local tablex = require("pl.tablex")
1010

11+
local AWS_PUBLIC_DOMAIN_PATTERN = "^(.+)(%.amazonaws%.com)$"
12+
local AWS_VPC_ENDPOINT_DOMAIN_PATTERN = "^(.+)(%.vpce%.amazonaws%.com)$"
1113

1214

1315
-- case-insensitive lookup help.
@@ -323,8 +325,11 @@ local function generate_service_methods(service)
323325
-- https://github.com/aws/aws-sdk-js/blob/307e82673b48577fce4389e4ce03f95064e8fe0d/lib/services/sts.js#L78-L82
324326
assert(service.config.region, "region is required when using STS regional endpoints")
325327

326-
if not service.config._regionalEndpointInjected then
327-
local pre, post = service.config.endpoint:match("^(.+)(%.amazonaws%.com)$")
328+
-- If the endpoint is a VPC endpoint DNS hostname then we don't need to inject the region
329+
-- VPC endpoint DNS hostnames always contain region, see
330+
-- https://docs.aws.amazon.com/vpc/latest/privatelink/privatelink-access-aws-services.html#interface-endpoint-dns-hostnames
331+
if not service.config._regionalEndpointInjected and not service.config.endpoint:match(AWS_VPC_ENDPOINT_DOMAIN_PATTERN) then
332+
local pre, post = service.config.endpoint:match(AWS_PUBLIC_DOMAIN_PATTERN)
328333
service.config.endpoint = pre .. "." .. service.config.region .. post
329334
service.config.signingRegion = service.config.region
330335
service.config._regionalEndpointInjected = true

0 commit comments

Comments
 (0)