This is an automated email from the ASF dual-hosted git repository.

sodonnell pushed a commit to branch HDDS-13323-sts
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/HDDS-13323-sts by this push:
     new 0f3b26b1b29 HDDS-14420. [STS] Add audit logging to endpoint and 
OzoneManager for STS (#9687)
0f3b26b1b29 is described below

commit 0f3b26b1b29b49cf1210b7896aa1895168884703
Author: fmorg-git <[email protected]>
AuthorDate: Fri Jan 30 07:52:39 2026 -0800

    HDDS-14420. [STS] Add audit logging to endpoint and OzoneManager for STS 
(#9687)
---
 .../apache/hadoop/ozone/client/ObjectStore.java    |   5 +-
 .../ozone/client/protocol/ClientProtocol.java      |   3 +-
 .../apache/hadoop/ozone/client/rpc/RpcClient.java  |   4 +-
 .../apache/hadoop/ozone/om/helpers/S3STSUtils.java |  44 ++++++++
 .../ozone/om/protocol/OzoneManagerProtocol.java    |   3 +-
 ...OzoneManagerProtocolClientSideTranslatorPB.java |   5 +-
 .../src/main/proto/OmClientProtocol.proto          |   1 +
 .../hadoop/ozone/om/helpers/OMAuditLogger.java     |   2 +
 .../request/s3/security/S3AssumeRoleRequest.java   |  81 ++++++++------
 .../s3/security/TestS3AssumeRoleRequest.java       | 105 +++++++++++++-----
 .../org/apache/hadoop/ozone/audit/S3GAction.java   |   5 +-
 .../ozone/s3/S3STSHeadersResponseFilter.java       |  49 ++++++++
 .../org/apache/hadoop/ozone/s3sts/Application.java |   3 +
 .../apache/hadoop/ozone/s3sts/S3STSEndpoint.java   | 123 ++++++++++++++-------
 .../hadoop/ozone/s3sts/S3STSEndpointBase.java      |  26 ++++-
 .../hadoop/ozone/client/ClientProtocolStub.java    |   8 +-
 .../hadoop/ozone/s3sts/TestS3STSEndpoint.java      |  73 ++++++++++--
 17 files changed, 415 insertions(+), 125 deletions(-)

diff --git 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java
 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java
index 4e6e1b0ae9d..f423979bde2 100644
--- 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java
+++ 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ObjectStore.java
@@ -758,12 +758,13 @@ public Iterator<OzoneSnapshotDiff> listSnapshotDiffJobs(
    * @param roleSessionName         The session name (should be unique) for 
this operation
    * @param durationSeconds         The duration in seconds for the token 
validity
    * @param awsIamSessionPolicy     The AWS IAM JSON session policy
+   * @param requestId               The requestId from the STS endpoint
    * @return AssumeRoleResponseInfo The AssumeRole response information 
containing temporary credentials
    * @throws IOException            if an error occurs during the AssumeRole 
operation
    */
   public AssumeRoleResponseInfo assumeRole(String roleArn, String 
roleSessionName, int durationSeconds,
-      String awsIamSessionPolicy) throws IOException {
-    return proxy.assumeRole(roleArn, roleSessionName, durationSeconds, 
awsIamSessionPolicy);
+      String awsIamSessionPolicy, String requestId) throws IOException {
+    return proxy.assumeRole(roleArn, roleSessionName, durationSeconds, 
awsIamSessionPolicy, requestId);
   }
 
   /**
diff --git 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/protocol/ClientProtocol.java
 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/protocol/ClientProtocol.java
index 88c28285616..96e8b654474 100644
--- 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/protocol/ClientProtocol.java
+++ 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/protocol/ClientProtocol.java
@@ -1367,11 +1367,12 @@ void deleteObjectTagging(String volumeName, String 
bucketName, String keyName)
    * @param roleSessionName         The session name (should be unique) for 
this operation
    * @param durationSeconds         The duration in seconds for the token 
validity
    * @param awsIamSessionPolicy     The AWS IAM JSON session policy
+   * @param requestId               The requestId from the STS endpoint
    * @return AssumeRoleResponseInfo The AssumeRole response information 
containing temporary credentials
    * @throws IOException            if an error occurs during the AssumeRole 
operation
    */
   AssumeRoleResponseInfo assumeRole(String roleArn, String roleSessionName, 
int durationSeconds,
-      String awsIamSessionPolicy) throws IOException;
+      String awsIamSessionPolicy, String requestId) throws IOException;
 
   /**
    * Revokes an STS token.
diff --git 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
index 67e2ac203bf..ef01ebd87e5 100644
--- 
a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
+++ 
b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java
@@ -2793,8 +2793,8 @@ public void deleteObjectTagging(String volumeName, String 
bucketName,
 
   @Override
   public AssumeRoleResponseInfo assumeRole(String roleArn, String 
roleSessionName, int durationSeconds,
-      String awsIamSessionPolicy) throws IOException {
-    return ozoneManagerClient.assumeRole(roleArn, roleSessionName, 
durationSeconds, awsIamSessionPolicy);
+      String awsIamSessionPolicy, String requestId) throws IOException {
+    return ozoneManagerClient.assumeRole(roleArn, roleSessionName, 
durationSeconds, awsIamSessionPolicy, requestId);
   }
 
   @Override
diff --git 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/S3STSUtils.java
 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/S3STSUtils.java
new file mode 100644
index 00000000000..8d261e6c68e
--- /dev/null
+++ 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/helpers/S3STSUtils.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.ozone.om.helpers;
+
+import com.google.common.base.Strings;
+import java.util.Map;
+
+/**
+ * Utility class containing constants and validation methods shared by STS 
endpoint and OzoneManager processing.
+ */
+public final class S3STSUtils {
+
+  private S3STSUtils() {
+  }
+
+  /**
+   * Adds standard AssumeRole audit params.
+   */
+  public static void addAssumeRoleAuditParams(Map<String, String> auditParams, 
String roleArn, String roleSessionName,
+      String awsIamSessionPolicy, int duration, String requestId) {
+
+    auditParams.put("action", "AssumeRole");
+    auditParams.put("roleArn", roleArn);
+    auditParams.put("roleSessionName", roleSessionName);
+    auditParams.put("duration", String.valueOf(duration));
+    auditParams.put("isPolicyIncluded", 
Strings.isNullOrEmpty(awsIamSessionPolicy) ? "N" : "Y");
+    auditParams.put("requestId", requestId);
+  }
+}
diff --git 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java
 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java
index 2661bc82366..5e4dafb925b 100644
--- 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java
+++ 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java
@@ -1184,11 +1184,12 @@ default void deleteObjectTagging(OmKeyArgs args) throws 
IOException {
    * @param roleSessionName         The session name (should be unique) for 
this operation
    * @param durationSeconds         The duration in seconds for the token 
validity
    * @param awsIamSessionPolicy     The AWS IAM JSON session policy
+   * @param requestId               The requestId from the STS endpoint
    * @return AssumeRoleResponseInfo The AssumeRole response information 
containing temporary credentials
    * @throws IOException            if an error occurs during the AssumeRole 
operation
    */
   default AssumeRoleResponseInfo assumeRole(String roleArn, String 
roleSessionName, int durationSeconds,
-      String awsIamSessionPolicy) throws IOException {
+      String awsIamSessionPolicy, String requestId) throws IOException {
     throw new UnsupportedOperationException("OzoneManager does not require 
this to be implemented");
   }
 
diff --git 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
index 8bbc3320dc1..8b778ae95d0 100644
--- 
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
+++ 
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
@@ -2659,13 +2659,14 @@ public void deleteObjectTagging(OmKeyArgs args) throws 
IOException {
 
   @Override
   public AssumeRoleResponseInfo assumeRole(String roleArn, String 
roleSessionName, int durationSeconds,
-      String awsIamSessionPolicy) throws IOException {
+      String awsIamSessionPolicy, String requestId) throws IOException {
     final OzoneManagerProtocolProtos.AssumeRoleRequest.Builder request =
         OzoneManagerProtocolProtos.AssumeRoleRequest.newBuilder()
             .setRoleArn(roleArn)
             .setRoleSessionName(roleSessionName)
             .setDurationSeconds(durationSeconds)
-            .setAwsIamSessionPolicy(awsIamSessionPolicy != null ? 
awsIamSessionPolicy : "");
+            .setAwsIamSessionPolicy(awsIamSessionPolicy != null ? 
awsIamSessionPolicy : "")
+            .setRequestId(requestId);
 
     final OMRequest omRequest = createOMRequest(Type.AssumeRole)
         .setAssumeRoleRequest(request)
diff --git 
a/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto 
b/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
index 00892f79a71..707f8ac567d 100644
--- a/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
+++ b/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
@@ -2379,6 +2379,7 @@ message AssumeRoleRequest {
   required string roleSessionName         = 2;
   optional int32 durationSeconds          = 3 [default = 3600];
   optional string awsIamSessionPolicy     = 4;
+  required string requestId               = 5;
 }
 
 message AssumeRoleResponse {
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/helpers/OMAuditLogger.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/helpers/OMAuditLogger.java
index e6185f3d65a..2c17d233547 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/helpers/OMAuditLogger.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/helpers/OMAuditLogger.java
@@ -95,6 +95,8 @@ private static void init() {
     CMD_AUDIT_ACTION_MAP.put(Type.GetObjectTagging, 
OMAction.GET_OBJECT_TAGGING);
     CMD_AUDIT_ACTION_MAP.put(Type.PutObjectTagging, 
OMAction.PUT_OBJECT_TAGGING);
     CMD_AUDIT_ACTION_MAP.put(Type.DeleteObjectTagging, 
OMAction.DELETE_OBJECT_TAGGING);
+    CMD_AUDIT_ACTION_MAP.put(Type.AssumeRole, OMAction.S3_ASSUME_ROLE);
+    CMD_AUDIT_ACTION_MAP.put(Type.RevokeSTSToken, OMAction.REVOKE_STS_TOKEN);
   }
 
   private static OMAction getAction(OzoneManagerProtocolProtos.OMRequest 
request) {
diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3AssumeRoleRequest.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3AssumeRoleRequest.java
index aecba45f32c..1b00454b70c 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3AssumeRoleRequest.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/s3/security/S3AssumeRoleRequest.java
@@ -24,19 +24,25 @@
 import java.net.InetAddress;
 import java.security.SecureRandom;
 import java.time.Clock;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.hadoop.hdds.scm.client.HddsClientUtils;
 import org.apache.hadoop.ipc.ProtobufRpcEngine;
+import org.apache.hadoop.ozone.audit.AuditLogger;
+import org.apache.hadoop.ozone.audit.OMAction;
 import org.apache.hadoop.ozone.om.OzoneAclUtils;
 import org.apache.hadoop.ozone.om.OzoneManager;
 import org.apache.hadoop.ozone.om.exceptions.OMException;
 import org.apache.hadoop.ozone.om.execution.flowcontrol.ExecutionContext;
+import org.apache.hadoop.ozone.om.helpers.S3STSUtils;
 import org.apache.hadoop.ozone.om.request.OMClientRequest;
 import org.apache.hadoop.ozone.om.request.util.OmResponseUtil;
 import org.apache.hadoop.ozone.om.response.OMClientResponse;
 import org.apache.hadoop.ozone.om.response.s3.security.S3AssumeRoleResponse;
+import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.AssumeRoleRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.AssumeRoleResponse;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRequest;
@@ -89,33 +95,39 @@ public OMClientResponse validateAndUpdateCache(OzoneManager 
ozoneManager, Execut
     final OMRequest omRequest = getOmRequest();
     final AssumeRoleRequest assumeRoleRequest = 
omRequest.getAssumeRoleRequest();
     final int durationSeconds = assumeRoleRequest.getDurationSeconds();
-
-    // Validate duration
-    if (durationSeconds < MIN_TOKEN_EXPIRATION_SECONDS || durationSeconds > 
MAX_TOKEN_EXPIRATION_SECONDS) {
-      final OMException omException = new OMException(
-          "Duration must be between " + MIN_TOKEN_EXPIRATION_SECONDS + " and " 
+ MAX_TOKEN_EXPIRATION_SECONDS,
-          OMException.ResultCodes.INVALID_REQUEST);
-      return new S3AssumeRoleResponse(
-          
createErrorOMResponse(OmResponseUtil.getOMResponseBuilder(omRequest), 
omException));
-    }
-
-    // Validate role session name
     final String roleSessionName = assumeRoleRequest.getRoleSessionName();
-    final S3AssumeRoleResponse roleSessionNameErrorResponse = 
validateRoleSessionName(roleSessionName, omRequest);
-    if (roleSessionNameErrorResponse != null) {
-      return roleSessionNameErrorResponse;
-    }
-
     final String roleArn = assumeRoleRequest.getRoleArn();
+    final String awsIamSessionPolicy = 
assumeRoleRequest.getAwsIamSessionPolicy();
+    final String requestId = assumeRoleRequest.getRequestId();
+
+    final Map<String, String> auditMap = new HashMap<>();
+    // In HA environments, only the tempAccessKeyId on the leader is used by 
S3G, so it could be helpful to
+    // have the leader information
+    auditMap.put("omRole", ozoneManager.isLeaderReady() ? "LEADER" : 
"FOLLOWER");
+    final AuditLogger auditLogger = ozoneManager.getAuditLogger();
+    final OzoneManagerProtocolProtos.UserInfo userInfo = 
omRequest.getUserInfo();
+    S3STSUtils.addAssumeRoleAuditParams(
+        auditMap, roleArn, roleSessionName, awsIamSessionPolicy, 
durationSeconds, requestId);
+
+    Exception exception = null;
+    OMClientResponse omClientResponse;
     try {
+      // Validate duration
+      if (durationSeconds < MIN_TOKEN_EXPIRATION_SECONDS || durationSeconds > 
MAX_TOKEN_EXPIRATION_SECONDS) {
+        throw new OMException(
+            "Duration must be between " + MIN_TOKEN_EXPIRATION_SECONDS + " and 
" + MAX_TOKEN_EXPIRATION_SECONDS,
+            OMException.ResultCodes.INVALID_REQUEST);
+      }
+
+      // Validate role session name
+      validateRoleSessionName(roleSessionName);
+
       // Validate role ARN and extract role
       final String targetRoleName = 
AwsRoleArnValidator.validateAndExtractRoleNameFromArn(roleArn);
 
       if (!omRequest.hasS3Authentication()) {
-        final String msg = "S3AssumeRoleRequest does not have S3 
authentication";
-        final OMException omException = new OMException(msg, 
OMException.ResultCodes.INVALID_REQUEST);
-        return new S3AssumeRoleResponse(
-            
createErrorOMResponse(OmResponseUtil.getOMResponseBuilder(omRequest), 
omException));
+        throw new OMException(
+            "S3AssumeRoleRequest does not have S3 authentication", 
OMException.ResultCodes.INVALID_REQUEST);
       }
 
       // Generate temporary AWS credentials using cryptographically strong 
SecureRandom
@@ -134,6 +146,9 @@ public OMClientResponse validateAndUpdateCache(OzoneManager 
ozoneManager, Execut
       // Calculate expiration of session token
       final long expirationEpochSeconds = 
clock.instant().plusSeconds(durationSeconds).getEpochSecond();
 
+      // Add tempAccessKeyId to the log so it can be determined which 
permanent user created the tempAccessKeyId
+      auditMap.put("tempAccessKeyId", tempAccessKeyId);
+
       final AssumeRoleResponse.Builder responseBuilder = 
AssumeRoleResponse.newBuilder()
           .setAccessKeyId(tempAccessKeyId)
           .setSecretAccessKey(secretAccessKey)
@@ -141,39 +156,41 @@ public OMClientResponse 
validateAndUpdateCache(OzoneManager ozoneManager, Execut
           .setExpirationEpochSeconds(expirationEpochSeconds)
           .setAssumedRoleId(assumedRoleId);
 
-      return new S3AssumeRoleResponse(
+      omClientResponse = new S3AssumeRoleResponse(
           OmResponseUtil.getOMResponseBuilder(omRequest)
               .setAssumeRoleResponse(responseBuilder.build())
               .build());
     } catch (OMException e) {
-      return new 
S3AssumeRoleResponse(createErrorOMResponse(OmResponseUtil.getOMResponseBuilder(omRequest),
 e));
+      exception = e;
+      omClientResponse = new S3AssumeRoleResponse(
+          
createErrorOMResponse(OmResponseUtil.getOMResponseBuilder(omRequest), e));
     } catch (IOException e) {
       final OMException omException = new OMException(
           "Failed to generate STS token for role: " + roleArn, e, 
OMException.ResultCodes.INTERNAL_ERROR);
-      return new S3AssumeRoleResponse(
+      exception = omException;
+      omClientResponse = new S3AssumeRoleResponse(
           
createErrorOMResponse(OmResponseUtil.getOMResponseBuilder(omRequest), 
omException));
     }
+
+    // Audit log
+    markForAudit(auditLogger, buildAuditMessage(OMAction.S3_ASSUME_ROLE, 
auditMap, exception, userInfo));
+
+    return omClientResponse;
   }
 
   /**
    * Ensures RoleSessionName is valid.
    */
-  private S3AssumeRoleResponse validateRoleSessionName(String roleSessionName, 
OMRequest omRequest) {
+  private void validateRoleSessionName(String roleSessionName) throws 
OMException {
     if (StringUtils.isBlank(roleSessionName)) {
-      final OMException omException = new OMException(
-          "RoleSessionName is required", 
OMException.ResultCodes.INVALID_REQUEST);
-      return new S3AssumeRoleResponse(
-          
createErrorOMResponse(OmResponseUtil.getOMResponseBuilder(omRequest), 
omException));
+      throw new OMException("RoleSessionName is required", 
OMException.ResultCodes.INVALID_REQUEST);
     }
     if (roleSessionName.length() < ASSUME_ROLE_SESSION_NAME_MIN_LENGTH ||
         roleSessionName.length() > ASSUME_ROLE_SESSION_NAME_MAX_LENGTH) {
-      final OMException omException = new OMException(
+      throw new OMException(
           "RoleSessionName length must be between " + 
ASSUME_ROLE_SESSION_NAME_MIN_LENGTH + " and " +
           ASSUME_ROLE_SESSION_NAME_MAX_LENGTH, 
OMException.ResultCodes.INVALID_REQUEST);
-      return new S3AssumeRoleResponse(
-          
createErrorOMResponse(OmResponseUtil.getOMResponseBuilder(omRequest), 
omException));
     }
-    return null;
   }
 
   /**
diff --git 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/s3/security/TestS3AssumeRoleRequest.java
 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/s3/security/TestS3AssumeRoleRequest.java
index 3ae3c3c7599..bda871386fe 100644
--- 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/s3/security/TestS3AssumeRoleRequest.java
+++ 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/s3/security/TestS3AssumeRoleRequest.java
@@ -23,6 +23,7 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.mockStatic;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -42,9 +43,12 @@
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
 import org.apache.hadoop.hdds.security.symmetric.ManagedSecretKey;
 import org.apache.hadoop.hdds.security.symmetric.SecretKeySignerClient;
+import org.apache.hadoop.ozone.audit.AuditLogger;
+import org.apache.hadoop.ozone.audit.AuditMessage;
 import org.apache.hadoop.ozone.om.OMMultiTenantManager;
 import org.apache.hadoop.ozone.om.OzoneManager;
 import org.apache.hadoop.ozone.om.execution.flowcontrol.ExecutionContext;
+import org.apache.hadoop.ozone.om.helpers.OMAuditLogger;
 import org.apache.hadoop.ozone.om.response.OMClientResponse;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.AssumeRoleRequest;
 import 
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.AssumeRoleResponse;
@@ -87,14 +91,21 @@ public class TestS3AssumeRoleRequest {
   private static final String OM_HOST = "om-host";
   private static final InetAddress LOOPBACK_IP = 
InetAddress.getLoopbackAddress();
   private static final Set<OzoneGrant> EMPTY_GRANTS = 
Collections.singleton(new OzoneGrant(emptySet(), emptySet()));
+  private static final String REQUEST_ID = UUID.randomUUID().toString();
+
+  private static final Pattern ABC_PATTERN_32 = Pattern.compile("^[ABC]{32}$");
+  private static final Pattern XYZ_PATTERN = Pattern.compile("^[XYZ]$");
 
   private OzoneManager ozoneManager;
   private ExecutionContext context;
   private IAccessAuthorizer accessAuthorizer;
+  private AuditLogger auditLogger;
 
   @BeforeEach
   public void setup() throws IOException {
     ozoneManager = mock(OzoneManager.class);
+    auditLogger = mock(AuditLogger.class);
+    when(ozoneManager.getAuditLogger()).thenReturn(auditLogger);
 
     final OzoneConfiguration configuration = new OzoneConfiguration();
     when(ozoneManager.getConfiguration()).thenReturn(configuration);
@@ -135,15 +146,17 @@ public void testInvalidDurationTooShort() {
                 .setRoleArn(ROLE_ARN_1)
                 .setRoleSessionName(SESSION_NAME)
                 .setDurationSeconds(899)  // less than 900
+                .setRequestId(REQUEST_ID)
         ).build();
 
-    final OMClientResponse response = new S3AssumeRoleRequest(omRequest, CLOCK)
-        .validateAndUpdateCache(ozoneManager, context);
+    final S3AssumeRoleRequest request = new S3AssumeRoleRequest(omRequest, 
CLOCK);
+    final OMClientResponse response = 
request.validateAndUpdateCache(ozoneManager, context);
     final OMResponse omResponse = response.getOMResponse();
 
     assertThat(omResponse.getStatus()).isEqualTo(Status.INVALID_REQUEST);
     assertThat(omResponse.getMessage()).isEqualTo("Duration must be between 
900 and 43200");
     assertThat(omResponse.hasAssumeRoleResponse()).isFalse();
+    assertMarkForAuditCalled(request);
   }
 
   @Test
@@ -154,15 +167,17 @@ public void testInvalidDurationTooLong() {
                 .setRoleArn(ROLE_ARN_1)
                 .setRoleSessionName(SESSION_NAME)
                 .setDurationSeconds(43201)  // more than 43200
+                .setRequestId(REQUEST_ID)
         ).build();
 
-    final OMClientResponse response = new S3AssumeRoleRequest(omRequest, CLOCK)
-        .validateAndUpdateCache(ozoneManager, context);
+    final S3AssumeRoleRequest request = new S3AssumeRoleRequest(omRequest, 
CLOCK);
+    final OMClientResponse response = 
request.validateAndUpdateCache(ozoneManager, context);
     final OMResponse omResponse = response.getOMResponse();
 
     assertThat(omResponse.getStatus()).isEqualTo(Status.INVALID_REQUEST);
     assertThat(omResponse.getMessage()).isEqualTo("Duration must be between 
900 and 43200");
     assertThat(omResponse.hasAssumeRoleResponse()).isFalse();
+    assertMarkForAuditCalled(request);
   }
 
   @Test
@@ -173,14 +188,16 @@ public void testValidDurationMaxBoundary() {
                 .setRoleArn(ROLE_ARN_1)
                 .setRoleSessionName(SESSION_NAME)
                 .setDurationSeconds(43200)  // exactly max
+                .setRequestId(REQUEST_ID)
         ).build();
 
-    final OMClientResponse response = new S3AssumeRoleRequest(omRequest, CLOCK)
-        .validateAndUpdateCache(ozoneManager, context);
+    final S3AssumeRoleRequest request = new S3AssumeRoleRequest(omRequest, 
CLOCK);
+    final OMClientResponse response = 
request.validateAndUpdateCache(ozoneManager, context);
     final OMResponse omResponse = response.getOMResponse();
 
     assertThat(omResponse.getStatus()).isEqualTo(Status.OK);
     assertThat(omResponse.hasAssumeRoleResponse()).isTrue();
+    assertMarkForAuditCalled(request);
   }
 
   @Test
@@ -191,14 +208,16 @@ public void testValidDurationMinBoundary() {
                 .setRoleArn(ROLE_ARN_1)
                 .setRoleSessionName(SESSION_NAME)
                 .setDurationSeconds(900)  // exactly min
+                .setRequestId(REQUEST_ID)
         ).build();
 
-    final OMClientResponse response = new S3AssumeRoleRequest(omRequest, CLOCK)
-        .validateAndUpdateCache(ozoneManager, context);
+    final S3AssumeRoleRequest request = new S3AssumeRoleRequest(omRequest, 
CLOCK);
+    final OMClientResponse response = 
request.validateAndUpdateCache(ozoneManager, context);
     final OMResponse omResponse = response.getOMResponse();
 
     assertThat(omResponse.getStatus()).isEqualTo(Status.OK);
     assertThat(omResponse.hasAssumeRoleResponse()).isTrue();
+    assertMarkForAuditCalled(request);
   }
 
   @Test
@@ -211,15 +230,17 @@ public void testMissingS3Authentication() {
                 .setRoleArn(ROLE_ARN_1)
                 .setRoleSessionName(SESSION_NAME)
                 .setDurationSeconds(3600)
+                .setRequestId(REQUEST_ID)
         ).build();
 
-    final OMClientResponse response = new S3AssumeRoleRequest(omRequest, CLOCK)
-        .validateAndUpdateCache(ozoneManager, context);
+    final S3AssumeRoleRequest request = new S3AssumeRoleRequest(omRequest, 
CLOCK);
+    final OMClientResponse response = 
request.validateAndUpdateCache(ozoneManager, context);
     final OMResponse omResponse = response.getOMResponse();
 
     assertThat(omResponse.getStatus()).isEqualTo(Status.INVALID_REQUEST);
     assertThat(omResponse.getMessage()).isEqualTo("S3AssumeRoleRequest does 
not have S3 authentication");
     assertThat(omResponse.hasAssumeRoleResponse()).isFalse();
+    assertMarkForAuditCalled(request);
   }
 
   @Test
@@ -231,10 +252,11 @@ public void 
testSuccessfulAssumeRoleGeneratesCredentials() {
                 .setRoleArn(ROLE_ARN_1)
                 .setRoleSessionName(SESSION_NAME)
                 .setDurationSeconds(durationSeconds)
+                .setRequestId(REQUEST_ID)
         ).build();
 
-    final OMClientResponse clientResponse = new S3AssumeRoleRequest(omRequest, 
CLOCK)
-        .validateAndUpdateCache(ozoneManager, context);
+    final S3AssumeRoleRequest request = new S3AssumeRoleRequest(omRequest, 
CLOCK);
+    final OMClientResponse clientResponse = 
request.validateAndUpdateCache(ozoneManager, context);
     final OMResponse omResponse = clientResponse.getOMResponse();
 
     assertThat(omResponse.getStatus()).isEqualTo(Status.OK);
@@ -260,6 +282,7 @@ public void testSuccessfulAssumeRoleGeneratesCredentials() {
     // Verify expiration added durationSeconds
     final long expirationEpochSeconds = 
assumeRoleResponse.getExpirationEpochSeconds();
     
assertThat(expirationEpochSeconds).isEqualTo(CLOCK.instant().getEpochSecond() + 
durationSeconds);
+    assertMarkForAuditCalled(request);
   }
 
   @Test
@@ -268,7 +291,7 @@ public void testGenerateSecureRandomStringUsingChars() {
     final int length = 32;
     final String s = S3AssumeRoleRequest.generateSecureRandomStringUsingChars(
         chars, chars.length(), length);
-    assertThat(s).hasSize(length).matches(Pattern.compile("^[ABC]{" + length + 
"}$"));
+    assertThat(s).hasSize(length).matches(ABC_PATTERN_32);
 
     // Test with length 0
     final String empty = 
S3AssumeRoleRequest.generateSecureRandomStringUsingChars(
@@ -278,7 +301,7 @@ public void testGenerateSecureRandomStringUsingChars() {
     // Test with length 1
     final String single = 
S3AssumeRoleRequest.generateSecureRandomStringUsingChars(
         "XYZ", 3, 1);
-    assertThat(single).hasSize(1).matches(Pattern.compile("^[XYZ]$"));
+    assertThat(single).hasSize(1).matches(XYZ_PATTERN);
   }
 
   @Test
@@ -290,12 +313,13 @@ public void testAssumeRoleCredentialsAreUnique() {
                 .setRoleArn(ROLE_ARN_1)
                 .setRoleSessionName(SESSION_NAME)
                 .setDurationSeconds(3600)
+                .setRequestId(REQUEST_ID)
         ).build();
 
-    final OMClientResponse response1 = new S3AssumeRoleRequest(omRequest, 
CLOCK)
-        .validateAndUpdateCache(ozoneManager, context);
-    final OMClientResponse response2 = new S3AssumeRoleRequest(omRequest, 
CLOCK)
-        .validateAndUpdateCache(ozoneManager, context);
+    final S3AssumeRoleRequest request1 = new S3AssumeRoleRequest(omRequest, 
CLOCK);
+    final OMClientResponse response1 = 
request1.validateAndUpdateCache(ozoneManager, context);
+    final S3AssumeRoleRequest request2 = new S3AssumeRoleRequest(omRequest, 
CLOCK);
+    final OMClientResponse response2 = 
request2.validateAndUpdateCache(ozoneManager, context);
 
     final AssumeRoleResponse assumeRoleResponse1 = 
response1.getOMResponse().getAssumeRoleResponse();
     final AssumeRoleResponse assumeRoleResponse2 = 
response2.getOMResponse().getAssumeRoleResponse();
@@ -311,6 +335,10 @@ public void testAssumeRoleCredentialsAreUnique() {
 
     // Different assumed role IDs
     
assertThat(assumeRoleResponse1.getAssumedRoleId()).isNotEqualTo(assumeRoleResponse2.getAssumedRoleId());
+
+    OMAuditLogger.log(request1.getAuditBuilder());
+    OMAuditLogger.log(request2.getAuditBuilder());
+    verify(auditLogger, times(2)).logWrite(any(AuditMessage.class));
   }
 
   @Test
@@ -321,12 +349,14 @@ public void testAssumeRoleWithEmptySessionName() {
                 .setRoleArn(ROLE_ARN_1)
                 .setRoleSessionName("")
                 .setDurationSeconds(3600)
+                .setRequestId(REQUEST_ID)
         ).build();
 
-    final OMClientResponse response = new S3AssumeRoleRequest(omRequest, CLOCK)
-        .validateAndUpdateCache(ozoneManager, context);
+    final S3AssumeRoleRequest request = new S3AssumeRoleRequest(omRequest, 
CLOCK);
+    final OMClientResponse response = 
request.validateAndUpdateCache(ozoneManager, context);
     
assertThat(response.getOMResponse().getStatus()).isEqualTo(Status.INVALID_REQUEST);
     
assertThat(response.getOMResponse().getMessage()).isEqualTo("RoleSessionName is 
required");
+    assertMarkForAuditCalled(request);
   }
 
   @Test
@@ -336,15 +366,17 @@ public void testInvalidAssumeRoleSessionNameTooShort() {
             AssumeRoleRequest.newBuilder()
                 .setRoleArn(ROLE_ARN_1)
                 .setRoleSessionName("T")   // Less than 2 characters
+                .setRequestId(REQUEST_ID)
         ).build();
 
-    final OMClientResponse response = new S3AssumeRoleRequest(omRequest, CLOCK)
-        .validateAndUpdateCache(ozoneManager, context);
+    final S3AssumeRoleRequest request = new S3AssumeRoleRequest(omRequest, 
CLOCK);
+    final OMClientResponse response = 
request.validateAndUpdateCache(ozoneManager, context);
     final OMResponse omResponse = response.getOMResponse();
 
     assertThat(omResponse.getStatus()).isEqualTo(Status.INVALID_REQUEST);
     assertThat(omResponse.getMessage()).isEqualTo("RoleSessionName length must 
be between 2 and 64");
     assertThat(omResponse.hasAssumeRoleResponse()).isFalse();
+    assertMarkForAuditCalled(request);
   }
 
   @Test
@@ -355,15 +387,17 @@ public void testInvalidRoleSessionNameTooLong() {
             AssumeRoleRequest.newBuilder()
                 .setRoleArn(ROLE_ARN_1)
                 .setRoleSessionName(tooLongRoleSessionName)
+                .setRequestId(REQUEST_ID)
         ).build();
 
-    final OMClientResponse response = new S3AssumeRoleRequest(omRequest, CLOCK)
-        .validateAndUpdateCache(ozoneManager, context);
+    final S3AssumeRoleRequest request = new S3AssumeRoleRequest(omRequest, 
CLOCK);
+    final OMClientResponse response = 
request.validateAndUpdateCache(ozoneManager, context);
     final OMResponse omResponse = response.getOMResponse();
 
     assertThat(omResponse.getStatus()).isEqualTo(Status.INVALID_REQUEST);
     assertThat(omResponse.getMessage()).isEqualTo("RoleSessionName length must 
be between 2 and 64");
     assertThat(omResponse.hasAssumeRoleResponse()).isFalse();
+    assertMarkForAuditCalled(request);
   }
 
   @Test
@@ -374,14 +408,16 @@ public void testValidRoleSessionNameMaxLengthBoundary() {
             AssumeRoleRequest.newBuilder()
                 .setRoleArn(ROLE_ARN_1)
                 .setRoleSessionName(roleSessionName)  // exactly max length
+                .setRequestId(REQUEST_ID)
         ).build();
 
-    final OMClientResponse response = new S3AssumeRoleRequest(omRequest, CLOCK)
-        .validateAndUpdateCache(ozoneManager, context);
+    final S3AssumeRoleRequest request = new S3AssumeRoleRequest(omRequest, 
CLOCK);
+    final OMClientResponse response = 
request.validateAndUpdateCache(ozoneManager, context);
     final OMResponse omResponse = response.getOMResponse();
 
     assertThat(omResponse.getStatus()).isEqualTo(Status.OK);
     assertThat(omResponse.hasAssumeRoleResponse()).isTrue();
+    assertMarkForAuditCalled(request);
   }
 
   @Test
@@ -391,14 +427,16 @@ public void testValidRoleSessionNameMinLengthBoundary() {
             AssumeRoleRequest.newBuilder()
                 .setRoleArn(ROLE_ARN_1)
                 .setRoleSessionName("TT")   // exactly min length
+                .setRequestId(REQUEST_ID)
         ).build();
 
-    final OMClientResponse response = new S3AssumeRoleRequest(omRequest, CLOCK)
-        .validateAndUpdateCache(ozoneManager, context);
+    final S3AssumeRoleRequest request = new S3AssumeRoleRequest(omRequest, 
CLOCK);
+    final OMClientResponse response = 
request.validateAndUpdateCache(ozoneManager, context);
     final OMResponse omResponse = response.getOMResponse();
 
     assertThat(omResponse.getStatus()).isEqualTo(Status.OK);
     assertThat(omResponse.hasAssumeRoleResponse()).isTrue();
+    assertMarkForAuditCalled(request);
   }
 
   @Test
@@ -411,11 +449,13 @@ public void testAssumeRoleWithSessionPolicyPresent() {
                 .setRoleSessionName(SESSION_NAME)
                 .setDurationSeconds(3600)
                 .setAwsIamSessionPolicy(sessionPolicy)
+                .setRequestId(REQUEST_ID)
         ).build();
 
-    final OMClientResponse response = new S3AssumeRoleRequest(omRequest, CLOCK)
-        .validateAndUpdateCache(ozoneManager, context);
+    final S3AssumeRoleRequest request = new S3AssumeRoleRequest(omRequest, 
CLOCK);
+    final OMClientResponse response = 
request.validateAndUpdateCache(ozoneManager, context);
     assertThat(response.getOMResponse().getStatus()).isEqualTo(Status.OK);
+    assertMarkForAuditCalled(request);
   }
 
   @Test
@@ -530,6 +570,11 @@ private static OMRequest.Builder baseOmRequestBuilder() {
                 .setAccessId(ORIGINAL_ACCESS_KEY_ID)
         );
   }
+
+  private void assertMarkForAuditCalled(S3AssumeRoleRequest request) {
+    OMAuditLogger.log(request.getAuditBuilder());
+    verify(auditLogger).logWrite(any(AuditMessage.class));
+  }
 }
 
 
diff --git 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/audit/S3GAction.java
 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/audit/S3GAction.java
index 6c295b7aafc..991e0be15f9 100644
--- 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/audit/S3GAction.java
+++ 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/audit/S3GAction.java
@@ -53,7 +53,10 @@ public enum S3GAction implements AuditAction {
   GET_OBJECT_TAGGING,
   PUT_OBJECT_TAGGING,
   DELETE_OBJECT_TAGGING,
-  PUT_OBJECT_ACL;
+  PUT_OBJECT_ACL,
+
+  // STS endpoint
+  ASSUME_ROLE;
 
   @Override
   public String getAction() {
diff --git 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/S3STSHeadersResponseFilter.java
 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/S3STSHeadersResponseFilter.java
new file mode 100644
index 00000000000..675f3139a29
--- /dev/null
+++ 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/S3STSHeadersResponseFilter.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.ozone.s3;
+
+import java.io.IOException;
+import javax.inject.Inject;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerResponseContext;
+import javax.ws.rs.container.ContainerResponseFilter;
+import javax.ws.rs.ext.Provider;
+import org.apache.hadoop.ozone.s3sts.S3STSEnabled;
+
+/**
+ * This class adds common header responses for STS requests.
+ */
+@Provider
+@S3STSEnabled
+public class S3STSHeadersResponseFilter implements ContainerResponseFilter {
+
+  @Inject
+  private RequestIdentifier requestIdentifier;
+
+  @Override
+  public void filter(ContainerRequestContext containerRequestContext,
+      ContainerResponseContext containerResponseContext) throws IOException {
+
+    // Add STS-specific headers
+    containerResponseContext.getHeaders().add("Server", "Ozone");
+    containerResponseContext.getHeaders()
+        .add("X-Amz-Sts-Extended-Request-Id", requestIdentifier.getAmzId());
+    containerResponseContext.getHeaders()
+        .add("x-amzn-RequestId", requestIdentifier.getRequestId());
+  }
+}
diff --git 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3sts/Application.java
 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3sts/Application.java
index 1605532db1c..b4db14dfa61 100644
--- 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3sts/Application.java
+++ 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3sts/Application.java
@@ -17,6 +17,7 @@
 
 package org.apache.hadoop.ozone.s3sts;
 
+import org.apache.hadoop.ozone.s3.S3STSHeadersResponseFilter;
 import org.apache.hadoop.ozone.s3.exception.OSTSExceptionMapper;
 import org.glassfish.jersey.server.ResourceConfig;
 
@@ -27,6 +28,8 @@ public class Application extends ResourceConfig {
   public Application() {
     packages("org.apache.hadoop.ozone.s3sts");
     register(org.apache.hadoop.ozone.s3.AuthorizationFilter.class);
+    register(org.apache.hadoop.ozone.s3.ClientIpFilter.class);
     register(OSTSExceptionMapper.class);
+    register(S3STSHeadersResponseFilter.class);
   }
 }
diff --git 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3sts/S3STSEndpoint.java
 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3sts/S3STSEndpoint.java
index 9d6b1b8d77f..62bef03586a 100644
--- 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3sts/S3STSEndpoint.java
+++ 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3sts/S3STSEndpoint.java
@@ -22,13 +22,15 @@
 import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
 import static javax.ws.rs.core.Response.Status.NOT_IMPLEMENTED;
 
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Strings;
 import java.io.IOException;
 import java.io.StringWriter;
 import java.time.Instant;
 import java.time.ZoneOffset;
 import java.time.format.DateTimeFormatter;
-import java.util.UUID;
+import java.util.Map;
+import javax.inject.Inject;
 import javax.ws.rs.FormParam;
 import javax.ws.rs.GET;
 import javax.ws.rs.POST;
@@ -40,8 +42,11 @@
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.Marshaller;
+import org.apache.hadoop.ozone.audit.S3GAction;
 import org.apache.hadoop.ozone.om.exceptions.OMException;
 import org.apache.hadoop.ozone.om.helpers.AssumeRoleResponseInfo;
+import org.apache.hadoop.ozone.om.helpers.S3STSUtils;
+import org.apache.hadoop.ozone.s3.RequestIdentifier;
 import org.apache.hadoop.ozone.s3.exception.OS3Exception;
 import org.apache.hadoop.ozone.s3.exception.OSTSException;
 import org.slf4j.Logger;
@@ -75,6 +80,11 @@ public class S3STSEndpoint extends S3STSEndpointBase {
   private static final String GET_ACCESS_KEY_INFO_ACTION = "GetAccessKeyInfo";
 
   private static final String EXPECTED_VERSION = "2011-06-15";
+  private static final String VALIDATION_ERROR = "ValidationError";
+  private static final String INVALID_ACTION = "InvalidAction";
+  private static final String INTERNAL_FAILURE = "InternalFailure";
+  private static final String ACCESS_DENIED = "AccessDenied";
+  private static final String INVALID_CLIENT_TOKEN_ID = "InvalidClientTokenId";
 
   // Default token duration (in seconds) - AWS default is 3600 (1 hour)
   // TODO - add these constants and also validations in a common place that 
both endpoint and backend can use
@@ -83,6 +93,14 @@ public class S3STSEndpoint extends S3STSEndpointBase {
   private static final int MIN_DURATION_SECONDS = 900;   // 15 minutes
   private static final int MAX_SESSION_POLICY_SIZE = 2048;
 
+  @Inject
+  private RequestIdentifier requestIdentifier;
+
+  @VisibleForTesting
+  public void setRequestIdentifier(RequestIdentifier requestIdentifier) {
+    this.requestIdentifier = requestIdentifier;
+  }
+
   /**
    * STS endpoint that handles GET requests with query parameters.
    * AWS STS supports both GET and POST requests.
@@ -133,7 +151,8 @@ public Response post(
 
   private Response handleSTSRequest(String action, String roleArn, String 
roleSessionName,
       Integer durationSeconds, String version, String awsIamSessionPolicy) 
throws OS3Exception {
-    final String requestId = UUID.randomUUID().toString();
+    final String requestId = requestIdentifier.getRequestId();
+    // NOTE: invalid, missing or unsupported actions are not added to the 
audit log
     try {
       if (action == null) {
         // Amazon STS has a different structure for the XML error response 
when the action is missing
@@ -154,10 +173,10 @@ private Response handleSTSRequest(String action, String 
roleArn, String roleSess
       case DECODE_AUTHORIZATION_MESSAGE_ACTION:
       case GET_ACCESS_KEY_INFO_ACTION:
         throw new OSTSException(
-            "InvalidAction", "Operation " + action + " is not supported yet.", 
NOT_IMPLEMENTED.getStatusCode());
+            INVALID_ACTION, "Operation " + action + " is not supported yet.", 
NOT_IMPLEMENTED.getStatusCode());
       default:
         throw new OSTSException(
-            "InvalidAction", "Could not find operation " + action + " for 
version " +
+            INVALID_ACTION, "Could not find operation " + action + " for 
version " +
             (version == null ? "NO_VERSION_SPECIFIED.  Expected version is: " 
+ EXPECTED_VERSION : version),
             BAD_REQUEST.getStatusCode());
       }
@@ -166,107 +185,136 @@ private Response handleSTSRequest(String action, String 
roleArn, String roleSess
     } catch (Exception ex) {
       LOG.error("Unexpected error during STS request", ex);
       throw new OSTSException(
-          "InternalFailure", "An internal error has occurred.", 
INTERNAL_SERVER_ERROR.getStatusCode(), "Receiver");
-    }
-  }
-
-  private int validateDuration(Integer durationSeconds) throws 
IllegalArgumentException {
-    if (durationSeconds == null) {
-      return DEFAULT_DURATION_SECONDS;
-    }
-
-    if (durationSeconds < MIN_DURATION_SECONDS || durationSeconds > 
MAX_DURATION_SECONDS) {
-      throw new IllegalArgumentException(
-          "Invalid Value: " + ROLE_DURATION_SECONDS_PARAM + " must be between 
" + MIN_DURATION_SECONDS +
-              " and " + MAX_DURATION_SECONDS + " seconds");
+          INTERNAL_FAILURE, "An internal error has occurred.", 
INTERNAL_SERVER_ERROR.getStatusCode(), "Receiver");
     }
-
-    return durationSeconds;
   }
 
   private Response handleAssumeRole(String roleArn, String roleSessionName, 
Integer durationSeconds,
       String awsIamSessionPolicy, String version, String requestId) throws 
OSTSException {
-    // Validate parameters
     final String action = "AssumeRole";
+    final Map<String, String> auditParams = getAuditParameters();
+    S3STSUtils.addAssumeRoleAuditParams(
+        auditParams, roleArn, roleSessionName, awsIamSessionPolicy,
+        durationSeconds == null ? DEFAULT_DURATION_SECONDS : durationSeconds,
+        requestId);
+
     int duration;
     try {
+      // Validate parameters
       duration = validateDuration(durationSeconds);
     } catch (IllegalArgumentException e) {
-      throw new OSTSException("ValidationError", e.getMessage(), 
BAD_REQUEST.getStatusCode());
+      final OSTSException exception = new OSTSException(VALIDATION_ERROR, 
e.getMessage(), BAD_REQUEST.getStatusCode());
+      
getAuditLogger().logWriteFailure(buildAuditMessageForFailure(S3GAction.ASSUME_ROLE,
 auditParams, exception));
+      throw exception;
     }
 
     if (version == null || !version.equals(EXPECTED_VERSION)) {
-      throw new OSTSException(
-          "InvalidAction", "Could not find operation " + action + " for 
version " +
+      final OSTSException exception = new OSTSException(
+          INVALID_ACTION, "Could not find operation " + action + " for version 
" +
           (version == null ? "NO_VERSION_SPECIFIED.  Expected version is: " + 
EXPECTED_VERSION : version),
           BAD_REQUEST.getStatusCode());
+      
getAuditLogger().logWriteFailure(buildAuditMessageForFailure(S3GAction.ASSUME_ROLE,
 auditParams, exception));
+      throw exception;
     }
 
     if (roleArn == null || roleArn.isEmpty()) {
-      throw new OSTSException(
-          "ValidationError", "Value null at 'roleArn' failed to satisfy 
constraint: Member must not be null",
+      final OSTSException exception = new OSTSException(
+          VALIDATION_ERROR, "Value null at 'roleArn' failed to satisfy 
constraint: Member must not be null",
           BAD_REQUEST.getStatusCode());
+      
getAuditLogger().logWriteFailure(buildAuditMessageForFailure(S3GAction.ASSUME_ROLE,
 auditParams, exception));
+      throw exception;
     }
 
     if (roleSessionName == null || roleSessionName.isEmpty()) {
-      throw new OSTSException(
-          "ValidationError", "Value null at 'roleSessionName' failed to 
satisfy constraint: Member must not be null",
+      final OSTSException exception = new OSTSException(
+          VALIDATION_ERROR, "Value null at 'roleSessionName' failed to satisfy 
constraint: Member must not be null",
           BAD_REQUEST.getStatusCode());
+      
getAuditLogger().logWriteFailure(buildAuditMessageForFailure(S3GAction.ASSUME_ROLE,
 auditParams, exception));
+      throw exception;
     }
 
     // Validate role session name format (AWS requirements)
     if (!isValidRoleSessionName(roleSessionName)) {
-      throw new OSTSException(
-          "ValidationError", "Invalid RoleSessionName: must be 2-64 characters 
long and " +
+      final OSTSException exception = new OSTSException(
+          VALIDATION_ERROR, "Invalid RoleSessionName: must be 2-64 characters 
long and " +
           "contain only alphanumeric characters, +, =, ,, ., @, -",
           BAD_REQUEST.getStatusCode());
+      
getAuditLogger().logWriteFailure(buildAuditMessageForFailure(S3GAction.ASSUME_ROLE,
 auditParams, exception));
+      throw exception;
     }
 
     // Check Policy size if available
     if (awsIamSessionPolicy != null && awsIamSessionPolicy.length() > 
MAX_SESSION_POLICY_SIZE) {
-      throw new OSTSException(
-          "ValidationError", "Value '" + awsIamSessionPolicy + "' at 'policy' 
failed to satisfy constraint: Member " +
+      final OSTSException exception = new OSTSException(
+          VALIDATION_ERROR, "Value '" + awsIamSessionPolicy + "' at 'policy' 
failed to satisfy constraint: Member " +
           "must have length less than or equal to 2048", 
BAD_REQUEST.getStatusCode());
+      
getAuditLogger().logWriteFailure(buildAuditMessageForFailure(S3GAction.ASSUME_ROLE,
 auditParams, exception));
+      throw exception;
     }
 
     final String assumedRoleUserArn;
     try {
       assumedRoleUserArn = toAssumedRoleUserArn(roleArn, roleSessionName);
     } catch (IllegalArgumentException e) {
-      throw new OSTSException("ValidationError", e.getMessage(), 
BAD_REQUEST.getStatusCode());
+      final OSTSException exception = new OSTSException(VALIDATION_ERROR, 
e.getMessage(), BAD_REQUEST.getStatusCode());
+      
getAuditLogger().logWriteFailure(buildAuditMessageForFailure(S3GAction.ASSUME_ROLE,
 auditParams, exception));
+      throw exception;
     }
 
     try {
       final AssumeRoleResponseInfo responseInfo = getClient()
           .getObjectStore()
-          .assumeRole(roleArn, roleSessionName, duration, awsIamSessionPolicy);
+          .assumeRole(roleArn, roleSessionName, duration, awsIamSessionPolicy, 
requestId);
       // Generate AssumeRole response
       final String responseXml = 
generateAssumeRoleResponse(assumedRoleUserArn, responseInfo, requestId);
+
+      
getAuditLogger().logWriteSuccess(buildAuditMessageForSuccess(S3GAction.ASSUME_ROLE,
 auditParams));
+
       return Response.ok(responseXml)
           .header("Content-Type", "text/xml")
           .build();
     } catch (IOException e) {
       LOG.error("Error during AssumeRole processing", e);
+
+      
getAuditLogger().logWriteFailure(buildAuditMessageForFailure(S3GAction.ASSUME_ROLE,
 auditParams, e));
+
       if (e instanceof OMException) {
         final OMException omException = (OMException) e;
         if (omException.getResult() == OMException.ResultCodes.ACCESS_DENIED ||
             omException.getResult() == 
OMException.ResultCodes.PERMISSION_DENIED ||
             omException.getResult() == OMException.ResultCodes.TOKEN_EXPIRED) {
           throw new OSTSException(
-              "AccessDenied", "User is not authorized to perform: 
sts:AssumeRole on resource: " + roleArn,
+              ACCESS_DENIED, "User is not authorized to perform: 
sts:AssumeRole on resource: " + roleArn,
               FORBIDDEN.getStatusCode());
         }
         if (omException.getResult() == OMException.ResultCodes.INVALID_TOKEN) {
           throw new OSTSException(
-              "InvalidClientTokenId", "The security token included in the 
request is invalid.",
+              INVALID_CLIENT_TOKEN_ID, "The security token included in the 
request is invalid.",
               FORBIDDEN.getStatusCode());
         }
       }
-      throw new OSTSException("InternalFailure", "An internal error has 
occurred.",
-          INTERNAL_SERVER_ERROR.getStatusCode(), "Receiver");
+      throw new OSTSException(
+          INTERNAL_FAILURE, "An internal error has occurred.", 
INTERNAL_SERVER_ERROR.getStatusCode(), "Receiver");
+    } catch (Exception e) {
+      
getAuditLogger().logWriteFailure(buildAuditMessageForFailure(S3GAction.ASSUME_ROLE,
 auditParams, e));
+      throw e;
     }
   }
 
+  private int validateDuration(Integer durationSeconds) throws 
IllegalArgumentException {
+    if (durationSeconds == null) {
+      return DEFAULT_DURATION_SECONDS;
+    }
+
+    if (durationSeconds < MIN_DURATION_SECONDS || durationSeconds > 
MAX_DURATION_SECONDS) {
+      throw new IllegalArgumentException(
+          "Invalid Value: " + ROLE_DURATION_SECONDS_PARAM + " must be between 
" + MIN_DURATION_SECONDS +
+              " and " + MAX_DURATION_SECONDS + " seconds");
+    }
+
+    return durationSeconds;
+  }
+
   private boolean isValidRoleSessionName(String roleSessionName) {
     if (roleSessionName.length() < 2 || roleSessionName.length() > 64) {
       return false;
@@ -335,6 +383,7 @@ private String toAssumedRoleUserArn(String roleArn, String 
roleSessionName) {
     }
 
     final String roleName = resource.substring("role/".length());
+    //noinspection StringBufferReplaceableByString
     final StringBuilder stringBuilder = new StringBuilder("arn:");
     stringBuilder.append(partition);
     stringBuilder.append(":sts::");
diff --git 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3sts/S3STSEndpointBase.java
 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3sts/S3STSEndpointBase.java
index 0de5e6c1374..027784b0edc 100644
--- 
a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3sts/S3STSEndpointBase.java
+++ 
b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3sts/S3STSEndpointBase.java
@@ -48,8 +48,18 @@ public class S3STSEndpointBase implements Auditor {
   @Inject
   private SignatureInfo signatureInfo;
 
-  protected static final AuditLogger AUDIT =
-      new AuditLogger(AuditLoggerType.S3GLOGGER);
+  protected static final AuditLogger DEFAULT_AUDIT = new 
AuditLogger(AuditLoggerType.S3GLOGGER);
+
+  private AuditLogger auditLogger = DEFAULT_AUDIT;
+
+  protected AuditLogger getAuditLogger() {
+    return auditLogger;
+  }
+
+  @VisibleForTesting
+  public void setAuditLogger(AuditLogger auditLogger) {
+    this.auditLogger = auditLogger;
+  }
 
   @PostConstruct
   public void initialization() {
@@ -70,6 +80,14 @@ private AuditMessage.Builder 
auditMessageBaseBuilder(AuditAction op,
     AuditMessage.Builder builder = new AuditMessage.Builder()
         .forOperation(op)
         .withParams(auditMap);
+    
+    if (signatureInfo != null) {
+      String accessId = signatureInfo.getAwsAccessId();
+      if (accessId != null && !accessId.isEmpty()) {
+        builder.setUser(accessId);
+      }
+    }
+
     if (context != null) {
       builder.atIp(AuditUtils.getClientIpAddress(context));
     }
@@ -111,4 +129,8 @@ public void setContext(ContainerRequestContext context) {
   public void setSignatureInfo(SignatureInfo signatureInfo) {
     this.signatureInfo = signatureInfo;
   }
+
+  protected Map<String, String> getAuditParameters() {
+    return AuditUtils.getAuditParameters(context);
+  }
 }
diff --git 
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/client/ClientProtocolStub.java
 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/client/ClientProtocolStub.java
index 477b6876af8..304349f4371 100644
--- 
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/client/ClientProtocolStub.java
+++ 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/client/ClientProtocolStub.java
@@ -805,12 +805,8 @@ public void deleteObjectTagging(String volumeName, String 
bucketName, String key
   }
 
   @Override
-  public AssumeRoleResponseInfo assumeRole(
-      String roleArn,
-      String roleSessionName,
-      int durationSeconds,
-      String awsIamSessionPolicy
-  ) throws IOException {
+  public AssumeRoleResponseInfo assumeRole(String roleArn, String 
roleSessionName, int durationSeconds,
+      String awsIamSessionPolicy, String requestId) throws IOException {
     return null;
   }
 
diff --git 
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3sts/TestS3STSEndpoint.java
 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3sts/TestS3STSEndpoint.java
index aefb525448b..34891d08945 100644
--- 
a/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3sts/TestS3STSEndpoint.java
+++ 
b/hadoop-ozone/s3gateway/src/test/java/org/apache/hadoop/ozone/s3sts/TestS3STSEndpoint.java
@@ -26,31 +26,37 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
 import static org.mockito.Mockito.when;
 
 import java.io.IOException;
 import java.io.StringReader;
 import java.time.Instant;
 import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.core.MultivaluedHashMap;
 import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
+import org.apache.hadoop.ozone.audit.AuditLogger;
+import org.apache.hadoop.ozone.audit.AuditMessage;
 import org.apache.hadoop.ozone.client.ObjectStore;
 import org.apache.hadoop.ozone.client.OzoneClient;
 import org.apache.hadoop.ozone.client.OzoneClientStub;
 import org.apache.hadoop.ozone.om.exceptions.OMException;
 import org.apache.hadoop.ozone.om.helpers.AssumeRoleResponseInfo;
 import org.apache.hadoop.ozone.s3.OzoneConfigurationHolder;
+import org.apache.hadoop.ozone.s3.RequestIdentifier;
 import org.apache.hadoop.ozone.s3.exception.OSTSException;
 import org.apache.hadoop.ozone.s3.signature.SignatureInfo;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.xml.sax.InputSource;
@@ -61,15 +67,13 @@
 public class TestS3STSEndpoint {
   private S3STSEndpoint endpoint;
   private ObjectStore objectStore;
+  private AuditLogger auditLogger;
   private static final String ROLE_ARN = 
"arn:aws:iam::123456789012:role/test-role";
   private static final String ROLE_SESSION_NAME = "test-session";
   private static final String ROLE_USER_ARN = 
"arn:aws:sts::123456789012:assumed-role/test-role/" + ROLE_SESSION_NAME;
   private static final String STS_NS = 
"https://sts.amazonaws.com/doc/2011-06-15/";;
   private static final String AWS_FAULT_NS = 
"http://webservices.amazon.com/AWSFault/2005-15-09";;
 
-  @Mock
-  private ContainerRequestContext context;
-
   @BeforeEach
   public void setup() throws Exception {
     OzoneConfiguration config = new OzoneConfiguration();
@@ -77,9 +81,16 @@ public void setup() throws Exception {
     OzoneConfigurationHolder.setConfiguration(config);
     OzoneClient clientStub = spy(new OzoneClientStub());
 
+    final ContainerRequestContext context = 
mock(ContainerRequestContext.class);
+    final RequestIdentifier requestIdentifier = mock(RequestIdentifier.class);
+    final UriInfo uriInfo = mock(UriInfo.class);
+    when(context.getUriInfo()).thenReturn(uriInfo);
+    when(uriInfo.getPathParameters()).thenReturn(new MultivaluedHashMap<>());
+    when(uriInfo.getQueryParameters()).thenReturn(new MultivaluedHashMap<>());
+
     // Stub assumeRole to return deterministic credentials.
     objectStore = mock(ObjectStore.class);
-    when(objectStore.assumeRole(anyString(), anyString(), anyInt(), any()))
+    when(objectStore.assumeRole(anyString(), anyString(), anyInt(), any(), 
anyString()))
         .thenReturn(new AssumeRoleResponseInfo(
             "ASIA1234567890123456",
             "mySecretAccessKey",
@@ -91,6 +102,12 @@ public void setup() throws Exception {
     endpoint = new S3STSEndpoint();
     endpoint.setClient(clientStub);
     endpoint.setContext(context);
+    auditLogger = mock(AuditLogger.class);
+    endpoint.setAuditLogger(auditLogger);
+    
+    when(requestIdentifier.getRequestId()).thenReturn("test-request-id");
+    endpoint.setRequestIdentifier(requestIdentifier);
+
     SignatureInfo signatureInfo = new 
SignatureInfo.Builder(SignatureInfo.Version.V4)
         .setAwsAccessId("test-user")
         .setSignature("some-signature")
@@ -105,6 +122,8 @@ public void testStsAssumeRoleValidForGetMethod() throws 
Exception {
         "AssumeRole", ROLE_ARN, ROLE_SESSION_NAME, 3600, "2011-06-15", null);
 
     assertEquals(200, response.getStatus());
+    verify(auditLogger).logWriteSuccess(any(AuditMessage.class));
+    verify(auditLogger, never()).logWriteFailure(any(AuditMessage.class));
 
     String responseXml = (String) response.getEntity();
     assertNotNull(responseXml);
@@ -141,6 +160,8 @@ public void testStsAssumeRoleValidForPostMethod() throws 
Exception {
     final Response response = endpoint.post("AssumeRole", ROLE_ARN, 
ROLE_SESSION_NAME, 3600, "2011-06-15", null);
 
     assertEquals(200, response.getStatus());
+    verify(auditLogger).logWriteSuccess(any(AuditMessage.class));
+    verify(auditLogger, never()).logWriteFailure(any(AuditMessage.class));
     final String responseXml = (String) response.getEntity();
     assertNotNull(responseXml);
 
@@ -174,6 +195,7 @@ public void testStsNullAction() throws Exception {
     final Response response = endpoint.get(null, ROLE_ARN, ROLE_SESSION_NAME, 
3600, "2011-06-15", null);
 
     assertEquals(400, response.getStatus());
+    verifyNoInteractions(auditLogger);
     final String errorMessage = (String) response.getEntity();
     assertEquals("<UnknownOperationException/>", errorMessage);
 
@@ -188,6 +210,7 @@ public void testStsUnsupportedActionWithVersionSupplied() 
throws Exception {
         endpoint.get("UnsupportedAction", ROLE_ARN, ROLE_SESSION_NAME, 3600, 
"2011-06-15", null));
 
     assertEquals(400, ex.getHttpCode());
+    verifyNoInteractions(auditLogger);
 
     final String requestId = "test-request-id";
     ex.setRequestId(requestId);
@@ -201,6 +224,7 @@ public void 
testStsUnsupportedActionWithVersionNotSupplied() throws Exception {
         endpoint.get("UnsupportedAction", ROLE_ARN, ROLE_SESSION_NAME, 3600, 
null, null));
 
     assertEquals(400, ex.getHttpCode());
+    verifyNoInteractions(auditLogger);
 
     final String requestId = "test-request-id";
     ex.setRequestId(requestId);
@@ -214,6 +238,8 @@ public void testStsAssumeRoleWithInvalidVersion() throws 
Exception {
         endpoint.get("AssumeRole", ROLE_ARN, ROLE_SESSION_NAME, 3600, 
"2000-01-01", null));
 
     assertEquals(400, ex.getHttpCode());
+    verify(auditLogger).logWriteFailure(any(AuditMessage.class));
+    verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
 
     final String requestId = "test-request-id";
     ex.setRequestId(requestId);
@@ -227,6 +253,8 @@ public void testStsInvalidDuration() throws Exception {
         endpoint.get("AssumeRole", ROLE_ARN, ROLE_SESSION_NAME, -1, 
"2011-06-15", null));
 
     assertEquals(400, ex.getHttpCode());
+    verify(auditLogger).logWriteFailure(any(AuditMessage.class));
+    verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
 
     final String requestId = "test-request-id";
     ex.setRequestId(requestId);
@@ -238,9 +266,11 @@ public void testStsNullDurationUsesDefault3600() throws 
Exception {
     final Response response = endpoint.get(
         "AssumeRole", ROLE_ARN, ROLE_SESSION_NAME, null, "2011-06-15", null);
     assertEquals(200, response.getStatus());
+    verify(auditLogger).logWriteSuccess(any(AuditMessage.class));
+    verify(auditLogger, never()).logWriteFailure(any(AuditMessage.class));
 
     final ArgumentCaptor<Integer> durationCaptor = 
ArgumentCaptor.forClass(Integer.class);
-    verify(objectStore).assumeRole(anyString(), anyString(), 
durationCaptor.capture(), any());
+    verify(objectStore).assumeRole(anyString(), anyString(), 
durationCaptor.capture(), any(), anyString());
     assertEquals(3600, durationCaptor.getValue());
   }
 
@@ -252,6 +282,8 @@ public void testStsPolicyTooLarge() throws Exception {
         endpoint.get("AssumeRole", ROLE_ARN, ROLE_SESSION_NAME, 3600, 
"2011-06-15", tooLargePolicy));
 
     assertEquals(400, ex.getHttpCode());
+    verify(auditLogger).logWriteFailure(any(AuditMessage.class));
+    verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
 
     final String requestId = "test-request-id";
     ex.setRequestId(requestId);
@@ -267,6 +299,8 @@ public void testStsInvalidRoleArn() throws Exception {
         endpoint.get("AssumeRole", invalidRoleArn, ROLE_SESSION_NAME, 3600, 
"2011-06-15", null));
 
     assertEquals(400, ex.getHttpCode());
+    verify(auditLogger).logWriteFailure(any(AuditMessage.class));
+    verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
 
     final String requestId = "test-request-id";
     ex.setRequestId(requestId);
@@ -280,6 +314,8 @@ public void testStsMissingRoleArn() throws Exception {
         endpoint.get("AssumeRole", null, ROLE_SESSION_NAME, 3600, 
"2011-06-15", null));
 
     assertEquals(400, ex.getHttpCode());
+    verify(auditLogger).logWriteFailure(any(AuditMessage.class));
+    verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
 
     final String requestId = "test-request-id";
     ex.setRequestId(requestId);
@@ -294,6 +330,8 @@ public void testStsInvalidRoleArnMissingRoleName() throws 
Exception {
 
     assertEquals(400, ex.getHttpCode());
     assertEquals("ValidationError", ex.getCode());
+    verify(auditLogger).logWriteFailure(any(AuditMessage.class));
+    verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
 
     final String requestId = "test-request-id";
     ex.setRequestId(requestId);
@@ -308,6 +346,8 @@ public void testStsInvalidRoleArnMissingAccountId() throws 
Exception {
 
     assertEquals(400, ex.getHttpCode());
     assertEquals("ValidationError", ex.getCode());
+    verify(auditLogger).logWriteFailure(any(AuditMessage.class));
+    verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
 
     final String requestId = "test-request-id";
     ex.setRequestId(requestId);
@@ -321,6 +361,7 @@ public void testStsWhenActionNotImplemented() throws 
Exception {
         endpoint.get("GetSessionToken", ROLE_ARN, ROLE_SESSION_NAME, 3600, 
"2011-06-15", null));
 
     assertEquals(501, ex.getHttpCode());
+    verifyNoInteractions(auditLogger);
 
     final String requestId = "test-request-id";
     ex.setRequestId(requestId);
@@ -334,6 +375,8 @@ public void testStsMissingRoleSessionName() throws 
Exception {
         endpoint.get("AssumeRole", ROLE_ARN, null, 3600, "2011-06-15", null));
 
     assertEquals(400, ex.getHttpCode());
+    verify(auditLogger).logWriteFailure(any(AuditMessage.class));
+    verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
 
     final String requestId = "test-request-id";
     ex.setRequestId(requestId);
@@ -347,6 +390,8 @@ public void 
testStsInvalidRoleSessionNameWithInvalidCharacter() throws Exception
         endpoint.get("AssumeRole", ROLE_ARN, invalidSession, 3600, 
"2011-06-15", null));
 
     assertEquals(400, ex.getHttpCode());
+    verify(auditLogger).logWriteFailure(any(AuditMessage.class));
+    verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
 
     final String requestId = "test-request-id";
     ex.setRequestId(requestId);
@@ -360,6 +405,8 @@ public void testStsInvalidRoleSessionNameTooShort() throws 
Exception {
         endpoint.get("AssumeRole", ROLE_ARN, invalidSession, 3600, 
"2011-06-15", null));
 
     assertEquals(400, ex.getHttpCode());
+    verify(auditLogger).logWriteFailure(any(AuditMessage.class));
+    verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
 
     final String requestId = "test-request-id";
     ex.setRequestId(requestId);
@@ -374,6 +421,8 @@ public void testStsInvalidRoleArnResourceType() throws 
Exception {
         endpoint.get("AssumeRole", invalidRoleArn, ROLE_SESSION_NAME, 3600, 
"2011-06-15", null));
 
     assertEquals(400, ex.getHttpCode());
+    verify(auditLogger).logWriteFailure(any(AuditMessage.class));
+    verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
 
     final String requestId = "test-request-id";
     ex.setRequestId(requestId);
@@ -382,13 +431,15 @@ public void testStsInvalidRoleArnResourceType() throws 
Exception {
 
   @Test
   public void testStsInternalFailureWhenBackendThrows() throws Exception {
-    when(objectStore.assumeRole(anyString(), anyString(), anyInt(), any()))
+    when(objectStore.assumeRole(anyString(), anyString(), anyInt(), any(), 
anyString()))
         .thenThrow(new RuntimeException("some unexpected error"));
 
     final OSTSException ex = assertThrows(OSTSException.class, () ->
         endpoint.get("AssumeRole", ROLE_ARN, ROLE_SESSION_NAME, 3600, 
"2011-06-15", null));
 
     assertEquals(500, ex.getHttpCode());
+    verify(auditLogger).logWriteFailure(any(AuditMessage.class));
+    verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
 
     final String requestId = "test-request-id";
     ex.setRequestId(requestId);
@@ -397,13 +448,15 @@ public void testStsInternalFailureWhenBackendThrows() 
throws Exception {
 
   @Test
   public void testStsAccessDenied() throws Exception {
-    when(objectStore.assumeRole(anyString(), anyString(), anyInt(), any()))
+    when(objectStore.assumeRole(anyString(), anyString(), anyInt(), any(), 
anyString()))
         .thenThrow(new OMException("Permission denied", 
OMException.ResultCodes.ACCESS_DENIED));
 
     final OSTSException ex = assertThrows(OSTSException.class, () ->
         endpoint.get("AssumeRole", ROLE_ARN, ROLE_SESSION_NAME, 3600, 
"2011-06-15", null));
 
     assertEquals(403, ex.getHttpCode());
+    verify(auditLogger).logWriteFailure(any(AuditMessage.class));
+    verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
 
     final String requestId = "test-request-id";
     ex.setRequestId(requestId);
@@ -413,13 +466,15 @@ public void testStsAccessDenied() throws Exception {
 
   @Test
   public void testStsIOExceptionWrappedAsInternalFailure() throws Exception {
-    when(objectStore.assumeRole(anyString(), anyString(), anyInt(), any()))
+    when(objectStore.assumeRole(anyString(), anyString(), anyInt(), any(), 
anyString()))
         .thenThrow(new IOException("An IO error occurred"));
 
     final OSTSException ex = assertThrows(OSTSException.class, () ->
         endpoint.get("AssumeRole", ROLE_ARN, ROLE_SESSION_NAME, 3600, 
"2011-06-15", null));
 
     assertEquals(500, ex.getHttpCode());
+    verify(auditLogger).logWriteFailure(any(AuditMessage.class));
+    verify(auditLogger, never()).logWriteSuccess(any(AuditMessage.class));
 
     final String requestId = "test-request-id";
     ex.setRequestId(requestId);


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to