AWS STS With Wasabi
    • 10 Jun 2024
    • 5 Minutes to read
    • PDF

    AWS STS With Wasabi

    • PDF

    Article summary

    How do I use AWS STS with Wasabi?

    AWS STS (AWS Security Token Service) is a service that lets you create temporary credentials to access your AWS resources. By merely changing the endpoint you can start using AWS STS with Wasabi.

    Send all STS requests to sts.wasabisys.com.

    This document discusses the use of AWS STS using JAVA SDK 2.X.

    At Wasabi we support the below API methods:

    1.  GetSessionToken

    Sample code to create a bucket using AWS Java SDK and GetSessionToken:

    // create the profile credentials provider
    ProfileCredentialsProvider provider = ProfileCredentialsProvider.builder()
            .profileName(credentialsProfile)
            .build();
    
    // create the stsClient using the profile credentials provider
    StsClient stsClient = StsClient.builder()
            .httpClientBuilder(ApacheHttpClient.builder())
            .endpointOverride(new URI(stsUri))
            .credentialsProvider(provider)
            .build();
    
    // create the get session token request to be used later
    GetSessionTokenRequest session_token_request = GetSessionTokenRequest.builder()
            .durationSeconds(900)
            .build();
    
    // getting the session token.
    GetSessionTokenResponse session_token_result = stsClient.getSessionToken(session_token_request);
    Credentials credentials = session_token_result.credentials();
    
    // retrieving the temporary credentials and the session token and creating AwsSessionCredentials
    // object to be used by the S3 client later
    AwsSessionCredentials sessionCredentials = AwsSessionCredentials.create(
            credentials.accessKeyId(),
            credentials.secretAccessKey(),
            credentials.sessionToken()
    );
    
    // creating the s3 client using the temporary credentials
    S3Client s3Client = S3Client.builder()
            .httpClientBuilder(ApacheHttpClient.builder())
            .endpointOverride(new URI(s3Uri))
            .credentialsProvider(StaticCredentialsProvider.create(sessionCredentials))
            .build();
    
    String bucketName = "test-bucket-created-from-sts-credentials";
    
    // creating the create bucket request
    CreateBucketRequest request = CreateBucketRequest
            .builder()
            .bucket(bucketName)
            .build();
    
    // creating the bucket!
    CreateBucketResponse response = s3Client.createBucket(request);
    
    if(response.sdkHttpResponse().isSuccessful()){
        System.out.println(String.format("Bucket '%s' created successfully!", bucketName));
    }else{
        System.out.println(String.format("Error when creating bucket '%s': '%s'", bucketName, response.sdkHttpResponse().statusText()));
    }

    AssumeRole allows the STS client to create temporary credentials by assuming an existing Wasabi role. This allows you to restrict the access of the temporary credentials before creating them. It is also required that the AssumeRole STS client should be created with the credentials of the sub-user and cannot be done with the root credentials. 

    Steps to create STS credentials using AssumeRole:

    AssumeRoleRequest assume_role = AssumeRoleRequest.builder()
            .roleArn(roleArn)
            .roleSessionName("test-session")
            .durationSeconds(900)
            .build();
    
    // create the profile credentials provider
    ProfileCredentialsProvider provider = ProfileCredentialsProvider.builder()
            .profileName(credentialsProfile)
            .build();
    
    // create the stsClient using the profile credentials provider
    StsClient stsClient = StsClient.builder()
            .httpClientBuilder(ApacheHttpClient.builder())
            .endpointOverride(new URI(stsUri))
            .credentialsProvider(provider)
            .build();
    
    //Get the credentials and session token
    Credentials assumedRoleCredentials = stsClient.assumeRole(assume_role).credentials();
    
    AwsSessionCredentials sessionCredentials = AwsSessionCredentials.create(
            assumedRoleCredentials.accessKeyId(),
            assumedRoleCredentials.secretAccessKey(),
            assumedRoleCredentials.sessionToken()
    );
    
    //Create S3 object with temp credentials
    S3Client s3Client = S3Client.builder()
            .httpClientBuilder(ApacheHttpClient.builder())
            .endpointOverride(new URI(s3Uri))
            .credentialsProvider(StaticCredentialsProvider.create(sessionCredentials))
            .build();
    
    //Perform bucket list operation
    String bucketName = "test-bucket-sts";
    System.out.println("Listing bucket contents " + bucketName + "\n");
    ListObjectsResponse response = s3Client.listObjects(ListObjectsRequest.builder()
            .bucket(bucketName)
            .build());
    
    System.out.println("No. of Objects = " + response.contents().size());
    long totalSize = 0;
    for (S3Object obj: response.contents()) {
        totalSize += obj.size();
    }
    System.out.println("Total size of objects: "+ totalSize);

    Steps to create STS credentials using AssumeRole while providing a policy:

    // policy that denies the creation of a bucket.
    String denyingPutsPolicy = """
            {
                "Version": "2012-10-17",
                "Statement": [
                  {
                    "Effect": "Allow",
                    "Action": "s3:*",
                    "Resource": ["*"]
                  },
                  {
                    "Effect": "Deny",
                    "Action": "s3:CreateBucket",
                    "Resource": ["*"]
                  }
                ]
              }
            """;
    
    AssumeRoleRequest assume_role = AssumeRoleRequest.builder()
            .roleArn(roleArn)
            .roleSessionName("test-session")
            .durationSeconds(900)
            .policy(denyingPutsPolicy)
            .build();
    
    // create the profile credentials provider
    ProfileCredentialsProvider provider = ProfileCredentialsProvider.builder()
            .profileName(credentialsProfile)
            .build();
    
    // create the stsClient using the profile credentials provider
    StsClient stsClient = StsClient.builder()
            .httpClientBuilder(ApacheHttpClient.builder())
            .endpointOverride(new URI(stsUri))
            .credentialsProvider(provider)
            .build();
    
    //Get the credentials and session token
    Credentials assumedRoleCredentials = stsClient.assumeRole(assume_role).credentials();
    
    AwsSessionCredentials sessionCredentials = AwsSessionCredentials.create(
            assumedRoleCredentials.accessKeyId(),
            assumedRoleCredentials.secretAccessKey(),
            assumedRoleCredentials.sessionToken()
    );
    
    //Create S3 object with temp credentials
    S3Client s3Client = S3Client.builder()
            .httpClientBuilder(ApacheHttpClient.builder())
            .endpointOverride(new URI(s3Uri))
            .credentialsProvider(StaticCredentialsProvider.create(sessionCredentials))
            .build();
    
    //Perform bucket list operation
    String bucketName = "test-bucket-sts";
    System.out.println("Listing bucket contents " + bucketName + "\n");
    ListObjectsResponse listObjectsResponse = s3Client.listObjects(ListObjectsRequest.builder()
            .bucket(bucketName)
            .build());
    
    System.out.println("Listing bucket content response: " + listObjectsResponse.sdkHttpResponse().statusCode());
    
    // trying to create a new bucket!
    String newBucket = "test-new-bucket-creation-with-assumed-role";
    CreateBucketRequest request = CreateBucketRequest.builder()
            .bucket(newBucket)
            .build();
    
    try {
        s3Client.createBucket(request);
    }catch (Exception ex){
        System.out.println("Unable to create bucket: "+ex.getMessage());
    }

    Returns details about the IAM user or role whose credentials are used to call the operation.

    // create the profile credentials provider
    ProfileCredentialsProvider provider = ProfileCredentialsProvider.builder()
            .profileName(credentialsProfile)
            .build();
    
    // create the stsClient using the profile credentials provider
    StsClient stsClient = StsClient.builder()
            .httpClientBuilder(ApacheHttpClient.builder())
            .endpointOverride(new URI(stsUri))
            .credentialsProvider(provider)
            .build();
    
    GetCallerIdentityResponse response = stsClient.getCallerIdentity();
    
    System.out.println("Caller identity: ");
    System.out.println("    Account : "+ response.account());
    System.out.println("    User id : "+ response.userId());
    System.out.println("    User arn: "+ response.arn());

    Attached to this KB, you can find a working solution for all the API calls mentioned above. You just need to enter the following values in the Examples.java file:

    static String s3Uri = "https://s3.wasabisys.com";
    static String stsUri = "https://sts.wasabisys.com";
    static String credentialsProfile = "PUT_THE_NAME_OF_YOUR_PROFILE_LOCATED_IN_AWS_CONFIG_FILE";
    static String roleArn = "ARN_OF_THE_ROLE_TO_BE_ASSUMED";

    NOTE: We are in the process of verifying older version(s) of Java for this use case. Having said that, we encourage customers to make use of Java 2.x as it's the newer version.

    How_do_I_use_AWS_STS_with_Wasabi__JAVA_SDK_2.X_.zip