Skip to content

feat: STS web identity creds resolver #1949

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 39 commits into from
Jun 17, 2025

Conversation

sichanyoo
Copy link
Contributor

@sichanyoo sichanyoo commented Jun 2, 2025

Companion PR:

Issue #

2380

Description of changes

  • SDK-side implementation of STS web identity credential identity resolver.
  • Uses new extension point in smithy-swift for AuthSchemeResolverGenerator. Writes a line that constructs & adds IdentityProvisingSTSClient struct instance into auth option's identityProperties.
  • *Contains generated STS client in AWSSDKIdentity module.

New/existing dependencies impact assessment, if applicable

Conventional Commits

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Copy link
Contributor Author

@sichanyoo sichanyoo left a comment

Choose a reason for hiding this comment

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

Comments to help with reviews.

@@ -4,7 +4,7 @@ included:
- Sources/Core/AWSSDKCommon/Sources
- Sources/Core/AWSSDKEventStreamsAuth/Sources
- Sources/Core/AWSSDKHTTPAuth/Sources
- Sources/Core/AWSSDKIdentity/Sources
- Sources/Core/AWSSDKIdentity/Sources/AWSSDKIdentity
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Limits swiftlint to be more specific, so the generated STS client files doesn't get linted.

@@ -129,12 +129,32 @@ private var runtimeTargets: [Target] {
),
.target(
name: "AWSSDKHTTPAuth",
dependencies: [.crt, .smithy, .clientRuntime, .smithyHTTPAuth, "AWSSDKIdentity", "AWSSDKChecksums"],
dependencies: [.crt, .smithy, .clientRuntime, .smithyHTTPAuth, "AWSSDKChecksums"],
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The generated STS client in AWSSDKIdentity depends on AWSClientRuntime.
That caused this circular dependency:

AWSSDKIdentity => AWSClientRuntime => AWSSDKHTTPAuth => AWSSDKIdentity

Removed AWSSDKIdentity dependency from AWSSDKHTTPAuth as needed.

Comment on lines 137 to 157
dependencies: [
.crt,
.smithy,
.clientRuntime,
.smithyIdentity,
.smithyIdentityAPI,
.smithyHTTPAPI,
.awsSDKCommon,
"AWSClientRuntime",
.smithyRetriesAPI,
.smithyRetries,
.smithyEventStreamsAPI,
.smithyEventStreamsAuthAPI,
.smithyEventStreams,
.smithyChecksumsAPI,
.smithyChecksums,
.smithyWaitersAPI,
.awsSDKHTTPAuth,
.awsSDKEventStreamsAuth,
.awsSDKChecksums,
],
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Generated STS client in AWSSDKIdentity module needs dependencies that service modules use.

@@ -160,7 +180,7 @@ private var runtimeTestTargets: [Target] {
),
.testTarget(
name: "AWSSDKEventStreamsAuthTests",
dependencies: ["AWSClientRuntime", "AWSSDKEventStreamsAuth", .smithyStreams, .smithyTestUtils],
dependencies: ["AWSClientRuntime", "AWSSDKEventStreamsAuth", "AWSSDKIdentity", .smithyStreams, .smithyTestUtils],
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was the only spot where AWSSDKIdentity module was actually needed under AWSSDKHTTPAuth/. So moved dependency directly to test module instead.

@@ -97,7 +97,7 @@ class STSAssumeRoleAWSCredentialIdentityResolverTests: XCTestCase {
))

// Construct STS client wih assume-role credentials provider.
let underlyingResolver = try DefaultAWSCredentialIdentityResolverChain()
let underlyingResolver = DefaultAWSCredentialIdentityResolverChain()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Remove unnecessary try, now that default chain init doesn't do any throwing operation. Not related to any of the changes in the PR; just done here because I saw build warning.

@@ -0,0 +1,82 @@
//
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Generated STS client file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Generated STS client file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Generated STS client file.

@@ -71,7 +71,8 @@ data class AwsService(
val modelFile: File,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Adds STS client generation into AWSSDKIdentity, as well as visibility codegen setting for the client.

Comment on lines +41 to +43
{ return ( STSWebIdentityAWSCredentialIdentityResolver(source: .env)) },
{ return ( STSWebIdentityAWSCredentialIdentityResolver(source: .configFile)) },
{ return ( ECSAWSCredentialIdentityResolver()) },
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The old STSWebIdentity creds resolver that depends on CRT tried to resolve from env, then from config file. New ordering with new implementation uses same ordering.

Sichan Yoo added 2 commits June 3, 2025 12:28
@@ -0,0 +1,31 @@
package software.amazon.smithy.aws.swift.codegen.customization.credentialresolverservices
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Model integration to remove all operations except assume role & assumer role web identity when generating internal STS client for credential resolvers.

Copy link
Contributor Author

@sichanyoo sichanyoo left a comment

Choose a reason for hiding this comment

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

More comments to help review, now that dependency inversion is complete.

Comment on lines +140 to +162
.target(
name: "InternalAWSSTS",
dependencies: [
.clientRuntime,
.awsClientRuntime,
.smithyRetriesAPI,
.smithyRetries,
.smithy,
.smithyIdentity,
.smithyIdentityAPI,
.smithyEventStreamsAPI,
.smithyEventStreamsAuthAPI,
.smithyEventStreams,
.smithyChecksumsAPI,
.smithyChecksums,
.smithyWaitersAPI,
.awsSDKCommon,
.awsSDKIdentity,
.awsSDKHTTPAuth,
.awsSDKEventStreamsAuth,
.awsSDKChecksums,
],
path: "Sources/Core/AWSSDKIdentity/Sources/InternalAWSSTS"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

InternalAWSSTS is separated out into its own target.

@@ -199,6 +223,7 @@ private func target(_ service: String) -> Target {
.awsSDKHTTPAuth,
.awsSDKEventStreamsAuth,
.awsSDKChecksums,
"InternalAWSSTS",
Copy link
Contributor Author

Choose a reason for hiding this comment

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

All services depend on InternalAWSSTS, used for credential resolution as needed.

@@ -0,0 +1,24 @@
//
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This protocl is what allows dependency inversion. The actual IdentityProvidingSTSClient struct that conforms to the protocol here will be generated under InternalAWSSTS. Then, the auth scheme resolver of each public service module will construct an instance of the IdentityProvidingSTSClient struct and save it to auth option's identityProperties. Over in STS web identity cred resolver in AWSSDKIdentity, we just use the protocol to call the getCredentialsWithWebIdentity. This allows AWSSDKIdentity to use InternalAWSSTS without having direct dependency.

Comment on lines +10 to +15
public enum InternalClientKeys {
/// The STS client to be used in credential resolution.
public static let internalSTSClientKey = AttributeKey<any IdentityProvidingSTSClient>(
name: "IdentityProvidingSTSClient"
)
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This attribute key is used by auth scheme resolvers (generated for each public service module) to save an instance of IdentityProvidingSTSClient into identityProperties attributes of auth option.

@@ -0,0 +1,42 @@
//
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Generated STS client file. This is the concrete implementation of IdenttiyProvidingSTSClient protocol. It constructs an instance of the internal STS client generated in InternalAWSSTS target, uses it to fetch creds, and returns AWSCredentialIdentity.

Comment on lines 63 to 69
AuthSchemeResolverGenerator { authOptionName, writer ->
writer.write(
"$authOptionName.identityProperties.set(key: \$N.internalSTSClientKey, value: \$N())",
AWSSDKIdentityTypes.InternalClientKeys,
InternalClientTypes.IdentityProvidingSTSClient,
)
}.render(ctx)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is where we use the new extension point added in companion smithy-swift PR. Allows us to construct & add IdentityProvidingSTSClient struct to identityProperties, without leaking type info in generic smithy codegen.

Comment on lines +60 to +69
val INTERNAL_AWS_STS =
SwiftDependency(
"InternalAWSSTS",
"main",
"0.0.1",
"aws-sdk-swift",
"../../../aws-sdk-swift",
"InternalAWSSTS",
SwiftDependency.DistributionMethod.SPR,
)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

New target that contains internal STS client generated for credential resolution purposes.

@@ -0,0 +1,100 @@
package software.amazon.smithy.aws.swift.codegen.customization.credentialresolverservices
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Customization to generate IdentityProvidingSTSClient struct under InternalAWSSTS.

@@ -0,0 +1,43 @@
package software.amazon.smithy.aws.swift.codegen.customization.credentialresolverservices
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The model integration that removes unused operations from internal service clients. For STS, we only need assumeRole and assumeRoleWithWebIdentity. Reduces runtime module size.

@sichanyoo sichanyoo requested a review from jbelkins June 12, 2025 18:50
@sichanyoo sichanyoo merged commit 34fe2eb into main Jun 17, 2025
31 checks passed
@sichanyoo sichanyoo deleted the feat/sts-web-identity-creds-resolver branch June 17, 2025 21:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants