Allow XPack user read-only access to index audit log (elastic/x-pack-elasticsearch#2906)

The default internal XPack user no longer has access to the security index, but it should have read-only access to the audit log so that watches can be triggered based on audit events (but cannot write audit records)

Original commit: elastic/x-pack-elasticsearch@5c37720dad
This commit is contained in:
Tim Vernum 2017-11-07 19:31:24 +11:00 committed by GitHub
parent 7fe8bf3080
commit 8e5855e62e
4 changed files with 64 additions and 6 deletions

View File

@ -5,6 +5,7 @@
*/
package org.elasticsearch.xpack.security.user;
import org.elasticsearch.xpack.security.audit.index.IndexAuditTrail;
import org.elasticsearch.xpack.security.authz.RoleDescriptor;
import org.elasticsearch.xpack.security.authz.permission.Role;
import org.elasticsearch.xpack.security.support.MetadataUtils;
@ -18,7 +19,9 @@ public class XPackUser extends User {
public static final String ROLE_NAME = NAME;
public static final Role ROLE = Role.builder(new RoleDescriptor(ROLE_NAME, new String[] { "all" },
new RoleDescriptor.IndicesPrivileges[] {
RoleDescriptor.IndicesPrivileges.builder().indices("/@&~(\\.security*)/").privileges("all").build()},
RoleDescriptor.IndicesPrivileges.builder().indices("/@&~(\\.security.*)/").privileges("all").build(),
RoleDescriptor.IndicesPrivileges.builder().indices(IndexAuditTrail.INDEX_NAME_PREFIX + "-*").privileges("read").build()
},
new String[] { "*" },
MetadataUtils.DEFAULT_RESERVED_METADATA), null).build();
public static final XPackUser INSTANCE = new XPackUser();

View File

@ -439,7 +439,10 @@ public abstract class SecurityIntegTestCase extends ESIntegTestCase {
}
protected InternalSecurityClient internalSecurityClient() {
Client client = client();
return internalSecurityClient(client());
}
protected InternalSecurityClient internalSecurityClient(Client client) {
return new InternalSecurityClient(client.settings(), client.threadPool(), client);
}

View File

@ -48,10 +48,8 @@ import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.function.Function;
@ -142,8 +140,8 @@ public class SecurityTribeIT extends NativeRealmIntegTestCase {
try {
cluster2.wipe(Collections.emptySet());
try {
// this is a hack to clean up the .security index since only the XPack user or superusers can delete it
cluster2.getInstance(InternalClient.class)
// this is a hack to clean up the .security index since only the XPackSecurity user or superusers can delete it
internalSecurityClient(cluster2.client())
.admin().indices().prepareDelete(IndexLifecycleManager.INTERNAL_SECURITY_INDEX).get();
} catch (IndexNotFoundException e) {
// ignore it since not all tests create this index...

View File

@ -0,0 +1,54 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.security.user;
import java.util.function.Predicate;
import org.elasticsearch.action.get.GetAction;
import org.elasticsearch.action.index.IndexAction;
import org.elasticsearch.action.search.SearchAction;
import org.elasticsearch.action.update.UpdateAction;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.security.SecurityLifecycleService;
import org.elasticsearch.xpack.security.audit.index.IndexAuditTrail;
import org.elasticsearch.xpack.security.audit.index.IndexNameResolver;
import org.hamcrest.Matchers;
import org.joda.time.DateTime;
public class XPackUserTests extends ESTestCase {
public void testXPackUserCanAccessNonSecurityIndices() {
final String action = randomFrom(GetAction.NAME, SearchAction.NAME, IndexAction.NAME);
final Predicate<String> predicate = XPackUser.ROLE.indices().allowedIndicesMatcher(action);
final String index = randomBoolean() ? randomAlphaOfLengthBetween(3, 12) : "." + randomAlphaOfLength(8);
assertThat(predicate.test(index), Matchers.is(true));
}
public void testXPackUserCannotAccessSecurityIndex() {
final String action = randomFrom(GetAction.NAME, SearchAction.NAME, IndexAction.NAME);
final Predicate<String> predicate = XPackUser.ROLE.indices().allowedIndicesMatcher(action);
assertThat(predicate.test(SecurityLifecycleService.SECURITY_INDEX_NAME), Matchers.is(false));
assertThat(predicate.test(SecurityLifecycleService.NEW_SECURITY_INDEX_NAME), Matchers.is(false));
}
public void testXPackUserCanReadAuditTrail() {
final String action = randomFrom(GetAction.NAME, SearchAction.NAME);
final Predicate<String> predicate = XPackUser.ROLE.indices().allowedIndicesMatcher(action);
assertThat(predicate.test(getAuditLogName()), Matchers.is(true));
}
public void testXPackUserCannotWriteToAuditTrail() {
final String action = randomFrom(IndexAction.NAME, UpdateAction.NAME);
final Predicate<String> predicate = XPackUser.ROLE.indices().allowedIndicesMatcher(action);
assertThat(predicate.test(getAuditLogName()), Matchers.is(false));
}
private String getAuditLogName() {
final DateTime date = new DateTime().plusDays(randomIntBetween(1, 360));
final IndexNameResolver.Rollover rollover = randomFrom(IndexNameResolver.Rollover.values());
return IndexNameResolver.resolve(IndexAuditTrail.INDEX_NAME_PREFIX, date, rollover);
}
}