Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -681,8 +681,8 @@ public void testGetRoles() throws Exception {

List<Role> roles = response.getRoles();
assertNotNull(response);
// 27 system roles plus the three we created
assertThat(roles.size(), equalTo(30));
// 28 system roles plus the three we created
assertThat(roles.size(), equalTo(31));
}

{
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/monitoring/configuring-filebeat.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ If {security-features} are enabled, you must provide a valid user ID and
password so that {filebeat} can connect to {kib}:

.. Create a user on the monitoring cluster that has the
{stack-ov}/built-in-roles.html[`kibana_user` built-in role] or equivalent
{stack-ov}/built-in-roles.html[`kibana_admin` built-in role] or equivalent
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does filebeat need to connect as kibana_admin or would a less privileged role suffice ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@legrego What's our recommendation here? What privileges does filebeat need in order to use the Kibana API to setup dashboards etc?

privileges.

.. Add the `username` and `password` settings to the {es} output information in
Expand Down
4 changes: 2 additions & 2 deletions x-pack/docs/en/security/authentication/oidc-guide.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -419,14 +419,14 @@ through either the
NOTE: You cannot use {stack-ov}/mapping-roles.html#mapping-roles-file[role mapping files]
to grant roles to users authenticating via OpenID Connect.

This is an example of a simple role mapping that grants the `kibana_user` role
This is an example of a simple role mapping that grants the `kibana_admin` role
to any user who authenticates against the `oidc1` OpenID Connect realm:

[source,console]
--------------------------------------------------
PUT /_security/role_mapping/oidc-kibana
{
"roles": [ "kibana_user" ],
"roles": [ "kibana_admin" ],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be wary of suggesting to add kibana_admin to all users of the realm as consumers of the docs tend to follow our examples verbatim

"enabled": true,
"rules": {
"field": { "realm.name": "oidc1" }
Expand Down
4 changes: 2 additions & 2 deletions x-pack/docs/en/security/authentication/saml-guide.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -636,14 +636,14 @@ through either the
NOTE: You cannot use {stack-ov}/mapping-roles.html#mapping-roles-file[role mapping files]
to grant roles to users authenticating via SAML.

This is an example of a simple role mapping that grants the `kibana_user` role
This is an example of a simple role mapping that grants the `kibana_admin` role
to any user who authenticates against the `saml1` realm:

[source,console]
--------------------------------------------------
PUT /_security/role_mapping/saml-kibana
{
"roles": [ "kibana_user" ],
"roles": [ "kibana_admin" ],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be wary of suggesting to add kibana_admin to all users of the realm as consumers of the docs tend to follow our examples verbatim

"enabled": true,
"rules": {
"field": { "realm.name": "saml1" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,14 @@ private static Map<String, RoleDescriptor> initializeReservedRoles() {
RoleDescriptor.ApplicationResourcePrivileges.builder()
.application("kibana-.kibana").resources("*").privileges("all").build() },
null, null,
MetadataUtils.DEFAULT_RESERVED_METADATA, null))
MetadataUtils.DEPRECATED_RESERVED_METADATA, null))
.put("kibana_admin", new RoleDescriptor("kibana_admin", null, null,
new RoleDescriptor.ApplicationResourcePrivileges[] {
RoleDescriptor.ApplicationResourcePrivileges.builder()
.application("kibana-.kibana")
.resources("*").privileges("all")
.build() },
null, null, MetadataUtils.DEFAULT_RESERVED_METADATA, null))
.put("monitoring_user", new RoleDescriptor("monitoring_user",
new String[] { "cluster:monitor/main", "cluster:monitor/xpack/info" },
new RoleDescriptor.IndicesPrivileges[] {
Expand Down Expand Up @@ -106,7 +113,7 @@ private static Map<String, RoleDescriptor> initializeReservedRoles() {
RoleDescriptor.ApplicationResourcePrivileges.builder()
.application("kibana-.kibana").resources("*").privileges("read").build() },
null, null,
MetadataUtils.DEFAULT_RESERVED_METADATA,
MetadataUtils.DEPRECATED_RESERVED_METADATA,
null))
.put(KibanaUser.ROLE_NAME, new RoleDescriptor(KibanaUser.ROLE_NAME,
new String[] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ public class MetadataUtils {

public static final String RESERVED_PREFIX = "_";
public static final String RESERVED_METADATA_KEY = RESERVED_PREFIX + "reserved";
public static final String DEPRECATED_METADATA_KEY = RESERVED_PREFIX + "deprecated";
public static final Map<String, Object> DEFAULT_RESERVED_METADATA = Map.of(RESERVED_METADATA_KEY, true);
public static final Map<String, Object> DEPRECATED_RESERVED_METADATA = Map.of(
RESERVED_METADATA_KEY, true,
DEPRECATED_METADATA_KEY, true
);

private MetadataUtils() {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@

import static org.hamcrest.Matchers.hasEntry;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.mockito.Mockito.mock;

/**
Expand All @@ -177,6 +178,7 @@ public void testIsReserved() {
assertThat(ReservedRolesStore.isReserved("foobar"), is(false));
assertThat(ReservedRolesStore.isReserved(SystemUser.ROLE_NAME), is(true));
assertThat(ReservedRolesStore.isReserved("transport_client"), is(true));
assertThat(ReservedRolesStore.isReserved("kibana_admin"), is(true));
assertThat(ReservedRolesStore.isReserved("kibana_user"), is(true));
assertThat(ReservedRolesStore.isReserved("ingest_admin"), is(true));
assertThat(ReservedRolesStore.isReserved("monitoring_user"), is(true));
Expand Down Expand Up @@ -388,13 +390,62 @@ public void testKibanaSystemRole() {
assertNoAccessAllowed(kibanaRole, RestrictedIndicesNames.RESTRICTED_NAMES);
}

public void testKibanaAdminRole() {
final TransportRequest request = mock(TransportRequest.class);
final Authentication authentication = mock(Authentication.class);

RoleDescriptor roleDescriptor = new ReservedRolesStore().roleDescriptor("kibana_admin");
assertNotNull(roleDescriptor);
assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true));
assertThat(roleDescriptor.getMetadata(), not(hasEntry("_deprecated", true)));

Role kibanaAdminRole = Role.builder(roleDescriptor, null).build();
assertThat(kibanaAdminRole.cluster().check(ClusterHealthAction.NAME, request, authentication), is(false));
assertThat(kibanaAdminRole.cluster().check(ClusterStateAction.NAME, request, authentication), is(false));
assertThat(kibanaAdminRole.cluster().check(ClusterStatsAction.NAME, request, authentication), is(false));
assertThat(kibanaAdminRole.cluster().check(PutIndexTemplateAction.NAME, request, authentication), is(false));
assertThat(kibanaAdminRole.cluster().check(ClusterRerouteAction.NAME, request, authentication), is(false));
assertThat(kibanaAdminRole.cluster().check(ClusterUpdateSettingsAction.NAME, request, authentication),
is(false));
assertThat(kibanaAdminRole.cluster().check(MonitoringBulkAction.NAME, request, authentication), is(false));
assertThat(kibanaAdminRole.cluster().check(DelegatePkiAuthenticationAction.NAME, request, authentication),
is(false));

assertThat(kibanaAdminRole.runAs().check(randomAlphaOfLengthBetween(1, 12)), is(false));

assertThat(kibanaAdminRole.indices().allowedIndicesMatcher(IndexAction.NAME).test("foo"), is(false));
assertThat(kibanaAdminRole.indices().allowedIndicesMatcher(IndexAction.NAME).test(".reporting"), is(false));
assertThat(
kibanaAdminRole.indices().allowedIndicesMatcher("indices:foo").test(randomAlphaOfLengthBetween(8, 24)),
is(false));

final String randomApplication = "kibana-" + randomAlphaOfLengthBetween(8, 24);
assertThat(kibanaAdminRole.application().grants(new ApplicationPrivilege(randomApplication, "app-random", "all"),
"*"), is(false));

final String application = "kibana-.kibana";
assertThat(kibanaAdminRole.application().grants(new ApplicationPrivilege(application, "app-foo", "foo"), "*"),
is(false));
assertThat(kibanaAdminRole.application().grants(new ApplicationPrivilege(application, "app-all", "all"), "*"),
is(true));

final String applicationWithRandomIndex = "kibana-.kibana_" + randomAlphaOfLengthBetween(8, 24);
assertThat(
kibanaAdminRole.application()
.grants(new ApplicationPrivilege(applicationWithRandomIndex, "app-random-index", "all"), "*"),
is(false));

assertNoAccessAllowed(kibanaAdminRole, RestrictedIndicesNames.RESTRICTED_NAMES);
}

public void testKibanaUserRole() {
final TransportRequest request = mock(TransportRequest.class);
final Authentication authentication = mock(Authentication.class);

RoleDescriptor roleDescriptor = new ReservedRolesStore().roleDescriptor("kibana_user");
assertNotNull(roleDescriptor);
assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true));
assertThat(roleDescriptor.getMetadata(), hasEntry("_deprecated", true));

Role kibanaUserRole = Role.builder(roleDescriptor, null).build();
assertThat(kibanaUserRole.cluster().check(ClusterHealthAction.NAME, request, authentication), is(false));
Expand Down Expand Up @@ -696,6 +747,7 @@ public void testKibanaDashboardOnlyUserRole() {
RoleDescriptor roleDescriptor = new ReservedRolesStore().roleDescriptor("kibana_dashboard_only_user");
assertNotNull(roleDescriptor);
assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true));
assertThat(roleDescriptor.getMetadata(), hasEntry("_deprecated", true));

Role dashboardsOnlyUserRole = Role.builder(roleDescriptor, null).build();
assertThat(dashboardsOnlyUserRole.cluster().check(ClusterHealthAction.NAME, request, authentication), is(false));
Expand Down