Skip to content

Commit

Permalink
[Reporting] Kibana Application Privileges for Reporting (#94966)
Browse files Browse the repository at this point in the history
* Implement Reporting features as subfeatures of applications

* add setting to the docker list

* update doc images

* finish docs

* Apply suggestions from code review

Co-authored-by: Kaarina Tungseth <kaarina.tungseth@elastic.co>

* Apply suggestions from code review

Co-authored-by: Kaarina Tungseth <kaarina.tungseth@elastic.co>

* Apply suggestions from code review

Co-authored-by: Kaarina Tungseth <kaarina.tungseth@elastic.co>

* typo fix

* "PDF / PNG Reports" => "Reporting"

* Update x-pack/plugins/reporting/server/config/index.ts

Co-authored-by: Larry Gregory <lgregorydev@gmail.com>

* Update x-pack/test/functional/apps/security/secure_roles_perm.js

Co-authored-by: Larry Gregory <lgregorydev@gmail.com>

* update ids of report privileges

* combine dashboard privileges into 1 group

* update jest snapshot

* fix tests

* fix tests

* updates from feedback

* add note

* update screenshot

* fix grammer

* fix bad link breaks in doc

* update doc heading

* Apply suggestions documentation feedback

Co-authored-by: gchaps <33642766+gchaps@users.noreply.github.com>

* simplify

* use const assertions

* Apply text change suggestion from code review

Co-authored-by: gchaps <33642766+gchaps@users.noreply.github.com>

* more test for oss_features and reporting subFeatures

* reduce loc diff

* fix snapshot

* fix flakiness in licensing plugin public functional tests

Co-authored-by: Kaarina Tungseth <kaarina.tungseth@elastic.co>
Co-authored-by: Larry Gregory <lgregorydev@gmail.com>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: gchaps <33642766+gchaps@users.noreply.github.com>
  • Loading branch information
5 people authored Apr 21, 2021
1 parent e39b8c6 commit 5a6eda2
Show file tree
Hide file tree
Showing 84 changed files with 2,321 additions and 710 deletions.
15 changes: 13 additions & 2 deletions docs/settings/reporting-settings.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -275,9 +275,20 @@ For information about {kib} memory limits, see <<production, using {kib} in a pr
every {kib} instance that has a unique <<kibana-index, `kibana.index`>>
setting. Defaults to `.reporting`.

| [[xpack-reporting-roles-enabled]] `xpack.reporting.roles.enabled`
| deprecated:[7.13.0,This setting must be set to `false` in 8.0.] When `true`, grants users
access to the {report-features} by assigning reporting roles, specified by `xpack.reporting.roles.allow`.
Granting access to users this way is deprecated. Set to `false` and use
{kibana-ref}/kibana-privileges.html[{kib} privileges] instead.
Defaults to `true`.

| `xpack.reporting.roles.allow`
| Specifies the roles in addition to superusers that can use reporting.
Defaults to `[ "reporting_user" ]`. +
| deprecated:[7.13.0,This setting will be removed in 8.0.] Specifies the roles,
in addition to superusers, that can generate reports, using the {ref}/security-api.html#security-role-apis[{es} role management APIs].
Requires `xpack.reporting.roles.enabled` to be `true`.
Granting access to users this way is deprecated. Use
{kibana-ref}/kibana-privileges.html[{kib} privileges] instead.
Defaults to `[ "reporting_user" ]`.

|===

Expand Down
13 changes: 9 additions & 4 deletions docs/user/reporting/index.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,15 @@ for different operating systems.
[[reporting-required-privileges]]
== Roles and privileges

To generate a report, you must have the `reporting_user` role. You also need
the appropriate {kib} privileges to access the objects that you
want to report on and the {es} indices. See <<secure-reporting, Reporting and security>>
for an example.
When security is enabled, access to the {report-features} is controlled by security privileges. In versions 7.12 and earlier, you can grant access to the {report-features}
by assigning users the `reporting_user` role in {es}. In 7.13 and later, you can configure *Reporting* to use
<<kibana-privileges, {kib} privileges>>. It is recommended that *Reporting* is configured to
use {kib} privileges by setting <<xpack-reporting-roles-enabled,`xpack.reporting.roles.enabled`>> to `false`. By using {kib} privileges, you can define
custom roles that grant *Reporting* privileges as sub-features of {kib} applications in *Role Management*.

Users must also have the {kib} privileges to access the saved objects and associated {es} indices included in the generated reports.
For an example, refer to <<secure-reporting, Reporting and
security>>.

[float]
[[manually-generate-reports]]
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
143 changes: 97 additions & 46 deletions docs/user/security/reporting.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,30 @@ For more information, see
////

[[reporting-app-users]]
To enable users to generate reports, you must assign them the built-in `reporting_user`
role. Users will also need the appropriate <<kibana-privileges, {kib} privileges>> to access the objects
to report on and the {es} indices.
Access to reporting features is limited to privileged users. In older versions of Kibana, you could only grant
users the privilege by assigning them the `reporting_user` role in Elasticsearch. In 7.13 and above, you have
the option to create your own roles that grant access to reporting features using <<kibana-privileges, {kib} privileges>>.

It is recommended that you set `xpack.reporting.roles.enabled: false` in your kibana.yml to begin using Kibana
privileges. This will allow users to only see Reporting widgets in applications when they have privilege to use
them.

[NOTE]
============================================================================
The default value of `xpack.reporting.roles.enabled` is `true` for 7.x versions of Kibana. To migrate users to the
new method of securing access to *Reporting*, you must explicitly set `xpack.reporting.roles.enabled: false` in
`kibana.yml`. In the next major version of Kibana, having this set to `false` will be the only valid configuration.
============================================================================

This document discusses how to create a role that grants access to reporting features using the new method of
Kibana application privileges.

[float]
[[reporting-roles-management-ui]]
=== If you are using the `native` realm
=== Create the role in the `native` realm

To assign roles, use the *Roles* UI or <<reporting-roles-user-api, user API>>.
This example shows how to use *Roles* page to create a user who has a custom role and the
`reporting_user` role.
To create roles, use the *Roles* UI or <<reporting-roles-user-api, user API>>. This example shows how to
create a role that grants reporting feature privileges in {kib} applications.

. Open the main menu, then click *Stack Management > Roles*.

Expand All @@ -42,60 +55,69 @@ For more information, see {ref}/security-privileges.html[Security privileges].
[role="screenshot"]
image::user/security/images/reporting-privileges-example.png["Reporting privileges"]

. Add space privileges.
. Add space privileges for the {kib} applications that allow access to the reporting options.
+
To allow users to create CSV reports in *Discover*, or PDF reports in *Canvas*,
*Visualize Library*, and *Dashboard*, click *Add Kibana privilege* for each application,
then select the privileges to generate
reports. For example, select *All* privileges for all features, or *Customize* to grant
the privilege to generate reports for only specific applications.
+
[role="screenshot"]
image::user/security/images/reporting-custom-role.png["Reporting custom role"]
+
[NOTE]
============================================================================
Granting users access to reporting features in any application also grants them access to manage their reports in *Stack Management > Reporting*.
============================================================================
+
Reporting users typically save searches, create
visualizations, and build dashboards. They require a space
that provides read and write privileges in
*Discover* and *Dashboard*.

. Save your new role.

. Open the main menu, then click *Stack Management > Users*, add a new user, and assign the user the built-in
`reporting_user` role and your new custom role, `custom_reporting_user`.

[float]
==== With a custom index

If you are using Reporting with a custom index,
the `xpack.reporting.index` setting should begin
with `.reporting-*`. The default {kib} system user has
`all` privileges against the `.reporting-*` pattern of indices.

[source,js]
xpack.reporting.index: '.reporting-custom-index'

If you use a different pattern for the `xpack.reporting.index` setting,
you must create a custom role with appropriate access to the index, similar
to the following:

. Open the main menu, then click *Stack Management > Roles*.
. Click *Create role*, then name the role `custom-reporting-user`.
. Specify the custom index and assign it the `all` index privilege.
. Open the main menu, then click *Stack Management > Users* and create a new user with
the `kibana_system` role and the `custom-reporting-user` role.
. Configure {kib} to use the new account:
[source,js]
elasticsearch.username: 'custom_kibana_system'
. Open the main menu, then click *Stack Management > Users*, add a new user, and assign the user
your new `custom_reporting_user` role.

[float]
[[reporting-roles-user-api]]
==== With the user API
This example uses the {ref}/security-api-put-user.html[user API] to create a user who has the
`reporting_user` role and the `kibana_admin` role:
This example uses the {ref}/security-api-put-role.html[role API] to create a role that
grants the privilege to generate reports in *Canvas*, *Discover*, *Visualize Library*, and *Dashboard*.
This role is meant to be granted to users in combination with other roles that grant read access
to the data in {es}, and at least read access in the applications
where they'll generate reports.

[source, sh]
---------------------------------------------------------------
POST /_security/user/reporter
POST /_security/role/custom_reporting_user
{
"password" : "x-pack-test-password",
"roles" : ["kibana_admin", "reporting_user"],
"full_name" : "Reporting User"
metadata: {},
elasticsearch: { cluster: [], indices: [], run_as: [] },
kibana: [
{
base: [],
feature: {
dashboard: [
'generate_report', <1>
'download_csv_report' <2>
],
discover: ['generate_report'], <3>
canvas: ['generate_report'], <4>
visualize: ['generate_report'], <5>
},
spaces: ['*'],
}
]
}
---------------------------------------------------------------
// CONSOLE

<1> Grants access to generate PNG and PDF reports in *Dashboard*.
<2> Grants access to download CSV files from saved search panels in *Dashboard*.
<3> Grants access to generate CSV reports from saved searches in *Discover*.
<4> Grants access to generate PDF reports in *Canvas*.
<5> Grants access to generate PNG and PDF reports in *Visualize Library*.

[float]
=== If you are using an external identity provider
=== When using an external provider

If you are using an external identity provider, such as
LDAP or Active Directory, you can either assign
Expand All @@ -113,6 +135,35 @@ reporting_user:
- "cn=Bill Murray,dc=example,dc=com"
--------------------------------------------------------------------------------

[float]
=== With a custom index

If you are using a custom index,
the `xpack.reporting.index` setting should begin
with `.reporting-*`. The default {kib} system user has
`all` privileges against the `.reporting-*` pattern of indices.

[source,js]
xpack.reporting.index: '.reporting-custom-index'

If you use a different pattern for the `xpack.reporting.index` setting,
you must create a custom `kibana_system` user with appropriate access to the index, similar
to the following:

. Open the main menu, then click *Stack Management > Roles*.
. Click *Create role*, then name the role `custom-reporting-user`.
. Specify the custom index and assign it the `all` index privilege.
. Open the main menu, then click *Stack Management > Users* and create a new user with
the `kibana_system` role and the `custom-reporting-user` role.
. Configure {kib} to use the new account:
[source,js]
elasticsearch.username: 'custom_kibana_system'

[NOTE]
============================================================================
Setting a custom index for *Reporting* is not supported in the next major version of Kibana.
============================================================================

[role="xpack"]
[[securing-reporting]]
=== Secure the reporting endpoints
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ kibana_vars=(
xpack.reporting.queue.pollIntervalErrorMultiplier
xpack.reporting.queue.timeout
xpack.reporting.roles.allow
xpack.reporting.roles.enabled
xpack.rollup.enabled
xpack.ruleRegistry.unsafe.write.enabled
xpack.searchprofiler.enabled
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/canvas/kibana.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
],
"optionalPlugins": [
"home",
"reporting",
"usageCollection"
],
"requiredBundles": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { ShareMenu } from '../share_menu.component';

storiesOf('components/WorkpadHeader/ShareMenu', module).add('default', () => (
<ShareMenu
includeReporting={true}
onCopy={action('onCopy')}
onExport={action('onExport')}
getExportUrl={(type: string) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ export type OnCloseFn = (type: CloseTypes) => void;
export type GetExportUrlFn = (type: ExportUrlTypes, layout: LayoutType) => string;

export interface Props {
/** Flag to include the Reporting option only if Reporting is enabled */
includeReporting: boolean;
/** Handler to invoke when an export URL is copied to the clipboard. */
onCopy: OnCopyFn;
/** Handler to invoke when an end product is exported. */
Expand All @@ -39,7 +41,12 @@ export interface Props {
/**
* The Menu for Exporting a Workpad from Canvas.
*/
export const ShareMenu: FunctionComponent<Props> = ({ onCopy, onExport, getExportUrl }) => {
export const ShareMenu: FunctionComponent<Props> = ({
includeReporting,
onCopy,
onExport,
getExportUrl,
}) => {
const [showFlyout, setShowFlyout] = useState(false);

const onClose = () => {
Expand Down Expand Up @@ -73,16 +80,18 @@ export const ShareMenu: FunctionComponent<Props> = ({ onCopy, onExport, getExpor
closePopover();
},
},
{
name: strings.getShareDownloadPDFTitle(),
icon: 'document',
panel: {
id: 1,
title: strings.getShareDownloadPDFTitle(),
content: getPDFPanel(closePopover),
},
'data-test-subj': 'sharePanel-PDFReports',
},
includeReporting
? {
name: strings.getShareDownloadPDFTitle(),
icon: 'document',
panel: {
id: 1,
title: strings.getShareDownloadPDFTitle(),
content: getPDFPanel(closePopover),
},
'data-test-subj': 'sharePanel-PDFReports',
}
: false,
{
name: strings.getShareWebsiteTitle(),
icon: <EuiIcon type="globe" size="m" />,
Expand All @@ -91,7 +100,7 @@ export const ShareMenu: FunctionComponent<Props> = ({ onCopy, onExport, getExpor
closePopover();
},
},
],
].filter(Boolean),
});

const shareControl = (togglePopover: React.MouseEventHandler<any>) => (
Expand Down Expand Up @@ -123,6 +132,7 @@ export const ShareMenu: FunctionComponent<Props> = ({ onCopy, onExport, getExpor
};

ShareMenu.propTypes = {
includeReporting: PropTypes.bool.isRequired,
onCopy: PropTypes.func.isRequired,
onExport: PropTypes.func.isRequired,
getExportUrl: PropTypes.func.isRequired,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export const ShareMenu = compose<ComponentProps, {}>(
withServices,
withProps(
({ workpad, pageCount, services }: Props & WithServicesProps): ComponentProps => ({
includeReporting: services.reporting.includeReporting(),
getExportUrl: (type, layout) => {
if (type === 'pdf') {
const pdfUrl = getPdfUrl(
Expand Down
2 changes: 2 additions & 0 deletions x-pack/plugins/canvas/public/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import { BehaviorSubject } from 'rxjs';
import { ChartsPluginSetup, ChartsPluginStart } from 'src/plugins/charts/public';
import { ReportingStart } from '../../reporting/public';
import {
CoreSetup,
CoreStart,
Expand Down Expand Up @@ -49,6 +50,7 @@ export interface CanvasSetupDeps {
export interface CanvasStartDeps {
embeddable: EmbeddableStart;
expressions: ExpressionsStart;
reporting?: ReportingStart;
inspector: InspectorStart;
uiActions: UiActionsStart;
charts: ChartsPluginStart;
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/canvas/public/services/context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export const ServicesProvider: FC<{
notify: specifiedProviders.notify.getService(),
platform: specifiedProviders.platform.getService(),
navLink: specifiedProviders.navLink.getService(),
reporting: specifiedProviders.reporting.getService(),
labs: specifiedProviders.labs.getService(),
};
return <context.Provider value={value}>{children}</context.Provider>;
Expand Down
4 changes: 4 additions & 0 deletions x-pack/plugins/canvas/public/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { navLinkServiceFactory } from './nav_link';
import { embeddablesServiceFactory } from './embeddables';
import { expressionsServiceFactory } from './expressions';
import { labsServiceFactory } from './labs';
import { reportingServiceFactory } from './reporting';

export { NotifyService } from './notify';
export { PlatformService } from './platform';
Expand Down Expand Up @@ -79,6 +80,7 @@ export const services = {
notify: new CanvasServiceProvider(notifyServiceFactory),
platform: new CanvasServiceProvider(platformServiceFactory),
navLink: new CanvasServiceProvider(navLinkServiceFactory),
reporting: new CanvasServiceProvider(reportingServiceFactory),
labs: new CanvasServiceProvider(labsServiceFactory),
};

Expand All @@ -90,6 +92,7 @@ export interface CanvasServices {
notify: ServiceFromProvider<typeof services.notify>;
platform: ServiceFromProvider<typeof services.platform>;
navLink: ServiceFromProvider<typeof services.navLink>;
reporting: ServiceFromProvider<typeof services.reporting>;
labs: ServiceFromProvider<typeof services.labs>;
}

Expand Down Expand Up @@ -117,4 +120,5 @@ export const {
platform: platformService,
navLink: navLinkService,
expressions: expressionsService,
reporting: reportingService,
} = services;
Loading

0 comments on commit 5a6eda2

Please sign in to comment.