diff --git a/src/main/java/org/opensearch/security/auditlog/impl/AbstractAuditLog.java b/src/main/java/org/opensearch/security/auditlog/impl/AbstractAuditLog.java index 6d0d85220a..b66ae35470 100644 --- a/src/main/java/org/opensearch/security/auditlog/impl/AbstractAuditLog.java +++ b/src/main/java/org/opensearch/security/auditlog/impl/AbstractAuditLog.java @@ -177,6 +177,7 @@ public void logFailedLogin(String effectiveUser, boolean securityadmin, String i msg.addRestRequestInfo(request, auditConfigFilter); msg.addInitiatingUser(initiatingUser); msg.addEffectiveUser(effectiveUser); + msg.addTenant(getTenant(request)); msg.addIsAdminDn(securityadmin); save(msg); @@ -195,6 +196,7 @@ public void logSucceededLogin(String effectiveUser, boolean securityadmin, Strin msg.addRestRequestInfo(request, auditConfigFilter); msg.addInitiatingUser(initiatingUser); msg.addEffectiveUser(effectiveUser); + msg.addTenant(getTenant(request)); msg.addIsAdminDn(securityadmin); save(msg); } @@ -210,6 +212,7 @@ public void logMissingPrivileges(String privilege, String effectiveUser, Securit msg.addRemoteAddress(remoteAddress); msg.addRestRequestInfo(request, auditConfigFilter); msg.addEffectiveUser(effectiveUser); + msg.addTenant(getTenant(request)); msg.addPrivilege(privilege); save(msg); } @@ -224,6 +227,7 @@ public void logGrantedPrivileges(String effectiveUser, SecurityRequest request) msg.addRemoteAddress(getRemoteAddress()); msg.addRestRequestInfo(request, auditConfigFilter); msg.addEffectiveUser(effectiveUser); + msg.addTenant(getTenant(request)); save(msg); } @@ -244,6 +248,7 @@ public void logMissingPrivileges(String privilege, TransportRequest request, Tas getUser(), null, null, + getTenant(), remoteAddress, request, getThreadContextHeaders(), @@ -281,6 +286,7 @@ public void logGrantedPrivileges(String privilege, TransportRequest request, Tas getUser(), null, null, + getTenant(), remoteAddress, request, getThreadContextHeaders(), @@ -319,6 +325,7 @@ public void logIndexEvent(String privilege, TransportRequest request, Task task) getUser(), null, null, + getTenant(), remoteAddress, request, getThreadContextHeaders(), @@ -517,6 +524,7 @@ public void logBadHeaders(TransportRequest request, String action, Task task) { getUser(), null, null, + getTenant(), remoteAddress, request, getThreadContextHeaders(), @@ -549,6 +557,7 @@ public void logBadHeaders(SecurityRequest request) { msg.addRemoteAddress(remoteAddress); msg.addRestRequestInfo(request, auditConfigFilter); msg.addEffectiveUser(getUser()); + msg.addTenant(getTenant(request)); save(msg); } @@ -569,6 +578,7 @@ public void logSecurityIndexAttempt(TransportRequest request, String action, Tas getUser(), false, null, + getTenant(), remoteAddress, request, getThreadContextHeaders(), @@ -606,6 +616,7 @@ public void logSSLException(TransportRequest request, Throwable t, String action getUser(), false, null, + getTenant(), remoteAddress, request, getThreadContextHeaders(), @@ -640,6 +651,7 @@ public void logSSLException(SecurityRequest request, Throwable t) { msg.addRestRequestInfo(request, auditConfigFilter); msg.addException(t); msg.addEffectiveUser(getUser()); + msg.addTenant(getTenant(request)); save(msg); } @@ -671,6 +683,7 @@ public void logDocumentRead(String index, String id, ShardId shardId, Map getThreadContextHeaders() { return threadPool.getThreadContext().getHeaders(); } diff --git a/src/main/java/org/opensearch/security/auditlog/impl/AuditMessage.java b/src/main/java/org/opensearch/security/auditlog/impl/AuditMessage.java index ded8cb3878..23772798b3 100644 --- a/src/main/java/org/opensearch/security/auditlog/impl/AuditMessage.java +++ b/src/main/java/org/opensearch/security/auditlog/impl/AuditMessage.java @@ -90,6 +90,7 @@ public final class AuditMessage { public static final String CATEGORY = "audit_category"; public static final String REQUEST_EFFECTIVE_USER = "audit_request_effective_user"; public static final String REQUEST_INITIATING_USER = "audit_request_initiating_user"; + public static final String REQUEST_TENANT = "audit_request_tenant"; public static final String UTC_TIMESTAMP = "@timestamp"; public static final String CLUSTER_NAME = "audit_cluster_name"; @@ -200,6 +201,12 @@ public void addEffectiveUser(String user) { } } + public void addTenant(String tenant) { + if (tenant != null && !tenant.isEmpty()) { + auditInfo.put(REQUEST_TENANT, tenant); + } + } + public void addPath(String path) { if (path != null) { auditInfo.put(REST_REQUEST_PATH, path); diff --git a/src/main/java/org/opensearch/security/auditlog/impl/RequestResolver.java b/src/main/java/org/opensearch/security/auditlog/impl/RequestResolver.java index ea4289150e..b3347bead5 100644 --- a/src/main/java/org/opensearch/security/auditlog/impl/RequestResolver.java +++ b/src/main/java/org/opensearch/security/auditlog/impl/RequestResolver.java @@ -71,6 +71,7 @@ public static List resolve( final String effectiveUser, final Boolean securityadmin, final String initiatingUser, + final String tenant, final TransportAddress remoteAddress, final TransportRequest request, final Map headers, @@ -97,6 +98,7 @@ public static List resolve( effectiveUser, securityadmin, initiatingUser, + tenant, remoteAddress, action, privilege, @@ -137,6 +139,7 @@ public static List resolve( effectiveUser, securityadmin, initiatingUser, + tenant, remoteAddress, action, privilege, @@ -161,6 +164,7 @@ private static AuditMessage resolveInner( final String effectiveUser, final Boolean securityadmin, final String initiatingUser, + final String tenant, final TransportAddress remoteAddress, final String action, final String priv, @@ -181,6 +185,7 @@ private static AuditMessage resolveInner( final AuditMessage msg = new AuditMessage(category, cs, origin, Origin.TRANSPORT); msg.addInitiatingUser(initiatingUser); msg.addEffectiveUser(effectiveUser); + msg.addTenant(tenant); msg.addRemoteAddress(remoteAddress); msg.addAction(action); diff --git a/src/test/java/org/opensearch/security/auditlog/integration/BasicAuditlogTest.java b/src/test/java/org/opensearch/security/auditlog/integration/BasicAuditlogTest.java index ce3916c616..33670c11b9 100644 --- a/src/test/java/org/opensearch/security/auditlog/integration/BasicAuditlogTest.java +++ b/src/test/java/org/opensearch/security/auditlog/integration/BasicAuditlogTest.java @@ -982,4 +982,49 @@ public void testSensitiveMethodRedaction() throws Exception { assertThat(TestAuditlogImpl.messages.size(), is(1)); Assert.assertTrue(TestAuditlogImpl.sb.toString().contains(expectedUpdateUserRequestBody)); } + + @Test + public void testTenantFieldOnAuthenticatedRestRequest() throws Exception { + final Settings settings = Settings.builder() + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE") + .build(); + setup(settings); + + final List messages = TestAuditlogImpl.doThenWaitForMessages(() -> { + final HttpResponse response = rh.executeGetRequest( + "_search", + encodeBasicHeader("admin", "admin"), + new BasicHeader("securitytenant", "engineering_tenant") + ); + assertThat(response.getStatusCode(), equalTo(HttpStatus.SC_OK)); + }, 2); + + messages.forEach(message -> assertThat(message.toJson(), message.getAsMap().get(AuditMessage.REQUEST_TENANT), equalTo("engineering_tenant"))); + validateMsgs(messages); + } + + @Test + public void testTenantFieldOnFailedLogin() throws Exception { + final Settings settings = Settings.builder() + .put("plugins.security.audit.type", TestAuditlogImpl.class.getName()) + .put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE") + .build(); + setup(settings); + + final List messages = TestAuditlogImpl.doThenWaitForMessages(() -> { + final HttpResponse response = rh.executeGetRequest( + "_search", + encodeBasicHeader("admin", "wrongpassword"), + new BasicHeader("securitytenant", "engineering_tenant") + ); + assertThat(response.getStatusCode(), equalTo(HttpStatus.SC_UNAUTHORIZED)); + }, 1); + + assertThat(messages.get(0).getCategory(), equalTo(AuditCategory.FAILED_LOGIN)); + assertThat(messages.get(0).getAsMap().get(AuditMessage.REQUEST_TENANT), equalTo("engineering_tenant")); + + validateMsgs(messages); + } }