A pure Java library for AWS IAM Roles Anywhere credential provisioning, eliminating the need for external credential helper tools.
AWS IAM Roles Anywhere allows workloads outside of AWS to obtain temporary AWS credentials using X.509 certificates. While AWS provides an official credential helper tool, this library offers several advantages:
- Zero Dependencies: No external tools required - everything is embedded in your Java application
- Native Integration: Works seamlessly with AWS SDK v2 credential providers
- Spring Boot Support: Auto-configuration for Spring Boot applications
- Production Ready: Comprehensive test coverage and async credential refresh support
- ✅ Support for both PKCS#1 and PKCS#8 private key formats
- ✅ X.509 certificate chain validation
- ✅ Automatic credential refresh with async support
- ✅ Spring Boot starter with auto-configuration
- ✅ Built on AWS SDK v2 and Apache HTTP Client
- ✅ Comprehensive test suite with mock AWS server
Add the appropriate dependency to your pom.xml:
Core Library (for standalone usage):
<dependency>
<groupId>in.neuw</groupId>
<artifactId>aws-iam-roles-anywhere-core</artifactId>
<version>1.0.6</version>
</dependency>Spring Boot Starter (recommended for Spring Boot apps):
<dependency>
<groupId>in.neuw</groupId>
<artifactId>aws-iam-roles-anywhere-starter</artifactId>
<version>1.0.6</version>
</dependency>import tools.jackson.databind.json.JsonMapper;
import in.neuw.aws.rolesanywhere.credentials.IAMRolesAnywhereSessionsCredentialsProvider;
import in.neuw.aws.rolesanywhere.props.AwsRolesAnywhereProperties;
import software.amazon.awssdk.services.s3.S3Client;
// Configure properties
AwsRolesAnywhereProperties properties = new AwsRolesAnywhereProperties();
properties.setRoleArn("arn:aws:iam::123456789012:role/MyRole");
properties.setProfileArn("arn:aws:rolesanywhere:us-east-1:123456789012:profile/uuid");
properties.setTrustAnchorArn("arn:aws:rolesanywhere:us-east-1:123456789012:trust-anchor/uuid");
properties.setRegion("us-east-1");
properties.setDurationSeconds(3600);
properties.setEncodedX509Certificate("BASE64_ENCODED_CERTIFICATE");
properties.setEncodedPrivateKey("BASE64_ENCODED_PRIVATE_KEY");
// Create credentials provider using builder
IAMRolesAnywhereSessionsCredentialsProvider credentialsProvider =
new IAMRolesAnywhereSessionsCredentialsProvider.Builder(properties, new JsonMapper())
.prefetch(true)
.asyncCredentialUpdateEnabled(false)
.build();
// Use with AWS SDK
S3Client s3Client = S3Client.builder()
.credentialsProvider(credentialsProvider)
.build();application.yml:
aws:
iam:
rolesanywhere:
region: us-east-1
role-arn: arn:aws:iam::123456789012:role/MyRole
profile-arn: arn:aws:rolesanywhere:us-east-1:123456789012:profile/uuid
trust-anchor-arn: arn:aws:rolesanywhere:us-east-1:123456789012:trust-anchor/uuid
encoded-x509-certificate: BASE64_ENCODED_CERTIFICATE
encoded-private-key: BASE64_ENCODED_PRIVATE_KEY
duration-seconds: 3600
prefetch: true
async-credential-update-enabled: trueJava Configuration:
@Configuration
public class AwsConfig {
@Bean
public S3Client s3Client(AwsCredentialsProvider credentialsProvider) {
return S3Client.builder()
.credentialsProvider(credentialsProvider)
.build();
}
}| Property | Description | Example |
|---|---|---|
roleArn |
ARN of the IAM role to assume | arn:aws:iam::123456789012:role/MyRole |
profileArn |
ARN of the Roles Anywhere profile | arn:aws:rolesanywhere:us-east-1:123456789012:profile/uuid |
trustAnchorArn |
ARN of the trust anchor | arn:aws:rolesanywhere:us-east-1:123456789012:trust-anchor/uuid |
region |
AWS region | us-east-1 |
encodedX509Certificate |
Base64 encoded X.509 certificate | LS0tLS1CRUdJTi... |
encodedPrivateKey |
Base64 encoded private key (PKCS#1 or PKCS#8) | LS0tLS1CRUdJTi... |
| Property | Default | Description |
|---|---|---|
durationSeconds |
3600 |
Credential validity duration (900-3600 seconds) |
roleSessionName |
null |
Custom session name for the assumed role |
prefetch |
true |
Enable credential pre-fetching |
asyncCredentialUpdateEnabled |
false |
Enable asynchronous credential refresh |
For certificate generation and setup, refer to the roles-anywhere-openssl repository.
- Private Keys: PKCS#1 (
-----BEGIN RSA PRIVATE KEY-----) and PKCS#8 (-----BEGIN PRIVATE KEY-----) - Certificates: X.509 PEM format (
-----BEGIN CERTIFICATE-----) - Certificate Chains: Multiple certificates concatenated in PEM format
core/- Core credential provider implementationstarter/- Spring Boot auto-configurationtests/- Comprehensive test suite
Run tests with: mvn clean verify
Without logging config the logs won't show up at all in the console.
For logging configuration, when just using the core library, you may use the following logback.xml example for reference:
<configuration>
<!-- Keep Apache HTTP logs minimal -->
<logger name="org.apache.http" level="WARN"/>
<logger name="org.apache.http.wire" level="OFF"/>
<logger name="org.apache.http.headers" level="OFF"/>
<logger name="in.neuw.aws" level="DEBUG"/> <!-- or INFO, etc. -->
<!-- Ensure other logs appear -->
<root level="DEBUG"> <!-- or INFO, DEBUG, WARN, ERROR -->
<appender-ref ref="STDOUT"/>
</root>
<!-- Console Appender (if missing) -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
</configuration>For logging configuration when using the starter, it is relatively straight forward, and spring boot will automatically help in there.
# example config for enabling debug logging for aws-iam-roles-anywhere-starter
logger.in.neuw.aws=DEBUG
Certificate/Key Format Errors
- Ensure certificates are in PEM format with proper headers (
-----BEGIN CERTIFICATE-----) - Verify private keys are either PKCS#1 (
-----BEGIN RSA PRIVATE KEY-----) or PKCS#8 (-----BEGIN PRIVATE KEY-----) - Check that Base64 encoding doesn't include line breaks or whitespace
Credential Refresh Issues
- Enable async credential refresh for long-running applications
- Verify network connectivity to AWS Roles Anywhere endpoints
- Check IAM role trust relationships and policies
Spring Boot Integration
- Ensure properties are correctly prefixed with
aws.iam.rolesanywhere - Verify auto-configuration is not excluded
| Version | Core's JDK Runtime |
Starter's JDK Runtime |
AWS SDK v2 | Spring Boot | Notes |
|---|---|---|---|---|---|
| 1.0.7 | 17 | 17 | 2.46.8 | 4.0.7 | JDK 17 only, Spring Boot 4.0.7 & AWS SDK 2.46.8 |
| 1.0.6 | 17 | 17 | 2.42.41 | 4.0.6 | JDK 17 only, Spring Boot 4.0.6 & AWS SDK 2.42.41 |
| 1.0.5 | 17 | 17 | 2.42.25 | 4.0.5 | JDK 17 only, Spring Boot 4.0.5 & AWS SDK 2.42.25 |
| 1.0.4 | 17 | 17 | 2.42.16 | 4.0.4 | JDK 17 only, Spring Boot 4.0.4 & AWS SDK 2.42.16 |
| 1.0.3 | 17 | 17 | 2.41.33 | 4.0.3 | JDK 17 only, Spring Boot 4.0.3 & AWS SDK 2.41.33 |
| 1.0.2 | 17 | 17 | 2.41.14 | 4.0.2 | JDK 17 only, Spring Boot 4.0.2 & AWS SDK 2.41.14 |
| 1.0.1 | 17 | 17 | 2.40.12 | 4.0.1 | JDK 17 only, Spring Boot 4.0.1 & AWS SDK 2.40.12 |
| 1.0.0 | 17 | 17 | 2.39.6 | 4.0.0 | JDK 17 only, along with JACKSON 3 support |
For older versions, refer to the release notes. For JDK 8 support, check out the 0.7.x branch.
The library requires Base64-encoded certificate and private key values. Here's how to encode your PEM files:
Encode a certificate:
base64 -i certificate.pemEncode a private key:
base64 -i private-key.keyimport java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
public class FileEncoder {
public static String encodeFile(String filePath) throws Exception {
byte[] fileContent = Files.readAllBytes(Paths.get(filePath));
return Base64.getEncoder().encodeToString(fileContent);
}
public static void main(String[] args) throws Exception {
String encodedCert = encodeFile("certificate.pem");
String encodedKey = encodeFile("private-key.key");
System.out.println("Encoded Certificate:");
System.out.println(encodedCert);
System.out.println("\nEncoded Private Key:");
System.out.println(encodedKey);
}
}- The encoded values should not contain line breaks when used in the configuration
- Keep the encoded private key secure - treat it with the same care as the original key file
- The PEM files must contain the proper headers (
-----BEGIN CERTIFICATE-----, etc.) before encoding - For certificate chains, complete chain needs to be encoded.
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the terms specified in the LICENSE file.