fixes #154 support AWS STS on the lambda invoker by stevehu · Pull Request #155 · networknt/light-aws-lambda · GitHub
Skip to content

fixes #154 support AWS STS on the lambda invoker#155

Merged
stevehu merged 8 commits into
masterfrom
issue154
Mar 20, 2026
Merged

fixes #154 support AWS STS on the lambda invoker#155
stevehu merged 8 commits into
masterfrom
issue154

Conversation

@stevehu

@stevehu stevehu commented Mar 20, 2026

Copy link
Copy Markdown
Contributor

No description provided.

Copilot AI left a comment

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.

Pull request overview

Adds optional AWS STS AssumeRole support to the lambda-invoker module so Lambda invocations can use short-lived assumed-role credentials configured via lambda-invoker settings.

Changes:

  • Add AWS SDK STS dependency to the parent and lambda-invoker modules.
  • Extend lambda-invoker configuration (YAML + LambdaInvokerConfig) with STS-related settings.
  • Update LambdaFunctionHandler to assume a role via STS, cache credentials, and refresh when nearing expiration.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
pom.xml Adds STS to dependencyManagement for consistent AWS SDK dependency versions.
lambda-invoker/pom.xml Adds module dependency on software.amazon.awssdk:sts.
lambda-invoker/src/main/resources/config/lambda-invoker.yml Documents new STS configuration options.
lambda-invoker/src/main/resources/config/lambda-invoker.yaml Same STS configuration documentation for .yaml variant.
lambda-invoker/src/main/java/com/networknt/aws/lambda/LambdaInvokerConfig.java Adds STS config fields + mapping into the config object.
lambda-invoker/src/main/java/com/networknt/aws/lambda/LambdaFunctionHandler.java Implements STS AssumeRole credential acquisition and refresh behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +109 to +138
if(config.isStsEnabled()) {
if(logger.isInfoEnabled()) logger.info("STS AssumeRole is enabled. Obtaining temporary credentials for role: {}", config.getRoleArn());
Credentials credentials = assumeRole(config);
stsCredentials = credentials;
credentialsExpiration = credentials.expiration();
AwsSessionCredentials sessionCredentials = AwsSessionCredentials.create(
credentials.accessKeyId(),
credentials.secretAccessKey(),
credentials.sessionToken()
);
builder.credentialsProvider(StaticCredentialsProvider.create(sessionCredentials));
}

return builder.build();
}

/**
* Call STS AssumeRole to obtain temporary credentials.
* @param config the lambda invoker config containing roleArn, roleSessionName, and durationSeconds
* @return the STS Credentials object containing temporary access key, secret key, session token, and expiration
*/
private Credentials assumeRole(LambdaInvokerConfig config) {
try (StsClient stsClient = StsClient.builder()
.region(Region.of(config.getRegion()))
.build()) {
AssumeRoleRequest assumeRoleRequest = AssumeRoleRequest.builder()
.roleArn(config.getRoleArn())
.roleSessionName(config.getRoleSessionName())
.durationSeconds(config.getDurationSeconds())
.build();

Copilot AI Mar 20, 2026

Copy link

Choose a reason for hiding this comment

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

When stsEnabled is true, roleArn and durationSeconds are not validated before building the AssumeRoleRequest. With the current defaults (roleArn empty, durationSeconds potentially 0 if omitted), this will fail at runtime with an SDK exception; add explicit validation and a clear error message (and enforce the 900–43200 durationSeconds bounds) before calling STS.

Copilot uses AI. Check for mistakes.

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.

@copilot open a new pull request to apply changes based on this feedback

Comment on lines +108 to +148
// If STS is enabled, obtain temporary credentials via AssumeRole
if(config.isStsEnabled()) {
if(logger.isInfoEnabled()) logger.info("STS AssumeRole is enabled. Obtaining temporary credentials for role: {}", config.getRoleArn());
Credentials credentials = assumeRole(config);
stsCredentials = credentials;
credentialsExpiration = credentials.expiration();
AwsSessionCredentials sessionCredentials = AwsSessionCredentials.create(
credentials.accessKeyId(),
credentials.secretAccessKey(),
credentials.sessionToken()
);
builder.credentialsProvider(StaticCredentialsProvider.create(sessionCredentials));
}

return builder.build();
}

/**
* Call STS AssumeRole to obtain temporary credentials.
* @param config the lambda invoker config containing roleArn, roleSessionName, and durationSeconds
* @return the STS Credentials object containing temporary access key, secret key, session token, and expiration
*/
private Credentials assumeRole(LambdaInvokerConfig config) {
try (StsClient stsClient = StsClient.builder()
.region(Region.of(config.getRegion()))
.build()) {
AssumeRoleRequest assumeRoleRequest = AssumeRoleRequest.builder()
.roleArn(config.getRoleArn())
.roleSessionName(config.getRoleSessionName())
.durationSeconds(config.getDurationSeconds())
.build();
AssumeRoleResponse response = stsClient.assumeRole(assumeRoleRequest);
if(logger.isInfoEnabled()) {
logger.info("STS AssumeRole succeeded. Credentials expire at: {}", response.credentials().expiration());
}
return response.credentials();
} catch (Exception e) {
logger.error("Failed to assume role via STS: {}", config.getRoleArn(), e);
throw new RuntimeException("Failed to assume role via STS", e);
}
}

Copilot AI Mar 20, 2026

Copy link

Choose a reason for hiding this comment

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

New STS behavior (assume-role request construction, validation, and refresh behavior) isn’t covered by tests. Since this module already has JUnit tests, add unit tests around the STS-enabled code path (e.g., validation errors for missing roleArn/invalid durationSeconds, and ensuring the chosen credentials provider is wired into the Lambda client).

Copilot uses AI. Check for mistakes.

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.

@copilot open a new pull request to apply changes based on this feedback

Comment on lines +155 to +189
@BooleanField(
configFieldName = STS_ENABLED,
externalizedKeyName = STS_ENABLED,
description = "Enable STS AssumeRole to obtain temporary credentials for Lambda invocation instead of using the\n" +
"permanent IAM credentials. When set to true, the handler will call STS AssumeRole with the configured\n" +
"roleArn, roleSessionName, and durationSeconds to get short-lived credentials. This is the recommended\n" +
"approach for production environments to follow the principle of least privilege.\n",
defaultValue = "false"
)
private boolean stsEnabled;

@StringField(
configFieldName = ROLE_ARN,
externalizedKeyName = ROLE_ARN,
description = "The ARN of the IAM role to assume when stsEnabled is true. For example,\n" +
"arn:aws:iam::123456789012:role/LambdaInvokerRole\n"
)
private String roleArn;

@StringField(
configFieldName = ROLE_SESSION_NAME,
externalizedKeyName = ROLE_SESSION_NAME,
description = "The session name to use when assuming the role. This is used for auditing and tracking in CloudTrail.",
defaultValue = "light-gateway-session"
)
private String roleSessionName;

@IntegerField(
configFieldName = DURATION_SECONDS,
externalizedKeyName = DURATION_SECONDS,
description = "The duration in seconds for the temporary credentials. Default is 3600 (1 hour). Minimum is 900 (15 min)\n" +
"and maximum is the role's max session duration setting (up to 43200 / 12 hours).\n",
defaultValue = "3600"
)
private int durationSeconds;

Copilot AI Mar 20, 2026

Copy link

Choose a reason for hiding this comment

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

This class is annotated for schema generation, but the checked-in lambda-invoker-schema.json needs to be regenerated/updated to include the new STS fields (stsEnabled/roleArn/roleSessionName/durationSeconds); otherwise config documentation and tooling will be out of sync.

Copilot uses AI. Check for mistakes.
Comment on lines +108 to +120
// If STS is enabled, obtain temporary credentials via AssumeRole
if(config.isStsEnabled()) {
if(logger.isInfoEnabled()) logger.info("STS AssumeRole is enabled. Obtaining temporary credentials for role: {}", config.getRoleArn());
Credentials credentials = assumeRole(config);
stsCredentials = credentials;
credentialsExpiration = credentials.expiration();
AwsSessionCredentials sessionCredentials = AwsSessionCredentials.create(
credentials.accessKeyId(),
credentials.secretAccessKey(),
credentials.sessionToken()
);
builder.credentialsProvider(StaticCredentialsProvider.create(sessionCredentials));
}

Copilot AI Mar 20, 2026

Copy link

Choose a reason for hiding this comment

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

The STS integration currently uses StaticCredentialsProvider with a one-time AssumeRole, then recreates the LambdaAsyncClient to refresh credentials. This is fragile and unnecessary with AWS SDK v2: prefer using StsAssumeRoleCredentialsProvider (or StsAssumeRoleCredentialsProvider.builder().refreshRequest(...)) so credentials are refreshed automatically without rebuilding/closing the shared client.

Copilot uses AI. Check for mistakes.

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.

@copilot open a new pull request to apply changes based on this feedback

Comment thread lambda-invoker/src/main/java/com/networknt/aws/lambda/LambdaFunctionHandler.java Outdated
Comment on lines +52 to +54
// STS credential cache fields
private Credentials stsCredentials;
private Instant credentialsExpiration;

Copilot AI Mar 20, 2026

Copy link

Choose a reason for hiding this comment

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

stsCredentials is assigned but never read anywhere. Remove it, or use it (e.g., for debugging/metrics) to avoid dead state that can confuse future maintainers.

Copilot uses AI. Check for mistakes.

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.

@copilot open a new pull request to apply changes based on this feedback

Comment thread lambda-invoker/src/main/java/com/networknt/aws/lambda/LambdaFunctionHandler.java Outdated
Comment thread lambda-invoker/src/main/resources/config/lambda-invoker.yml Outdated
Comment thread lambda-invoker/src/main/resources/config/lambda-invoker.yaml Outdated

Copilot AI commented Mar 20, 2026

Copy link
Copy Markdown
Contributor

@stevehu I've opened a new pull request, #156, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI commented Mar 20, 2026

Copy link
Copy Markdown
Contributor

@stevehu I've opened a new pull request, #157, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI commented Mar 20, 2026

Copy link
Copy Markdown
Contributor

@stevehu I've opened a new pull request, #158, to work on those changes. Once the pull request is ready, I'll request review from you.

…nctionHandler.java

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

Copilot AI commented Mar 20, 2026

Copy link
Copy Markdown
Contributor

stevehu and others added 6 commits March 20, 2026 09:13
…nctionHandler.java

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Initial plan

* Add validation for roleArn and durationSeconds before STS AssumeRole

Co-authored-by: stevehu <2042337+stevehu@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: stevehu <2042337+stevehu@users.noreply.github.com>
* Initial plan

* Add unit tests for STS code path in LambdaFunctionHandler

Co-authored-by: stevehu <2042337+stevehu@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: stevehu <2042337+stevehu@users.noreply.github.com>
Co-authored-by: Steve Hu <stevehu@gmail.com>
…resh (#158)

* Initial plan

* Replace StaticCredentialsProvider with StsAssumeRoleCredentialsProvider for automatic credential refresh

Co-authored-by: stevehu <2042337+stevehu@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: stevehu <2042337+stevehu@users.noreply.github.com>
Co-authored-by: Steve Hu <stevehu@gmail.com>
@stevehu stevehu merged commit 83cba86 into master Mar 20, 2026
1 check passed
@stevehu stevehu deleted the issue154 branch March 20, 2026 14:42
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.

3 participants