Skip to content

Commit

Permalink
[8.x] [ResponseOps][Alerting] Fix stackAlerts plugin missing rac API …
Browse files Browse the repository at this point in the history
…auth scope (#193948) (#195279)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[ResponseOps][Alerting] Fix stackAlerts plugin missing rac API auth
scope (#193948)](#193948)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Umberto
Pepato","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-10-07T15:17:31Z","message":"[ResponseOps][Alerting]
Fix stackAlerts plugin missing rac API auth scope (#193948)\n\n##
Summary\r\n\r\nAdds the `['rac']` API access scope to the Stack Alerts
feature to\r\ncorrectly authenticate alerts API endpoints with the
`stackAlerts`\r\npermission.\r\nAlso adds a dedicated API integration
test for the impacted endpoint and\r\npermission set.\r\n\r\n## Release
note\r\n\r\nFix Stack Alerts feature API access control\r\n\r\n## To
verify\r\n\r\n1. Create rules that fire alerts in Stack management\r\n2.
Wait for alerts to be created\r\n3. Create a role with only `Stack
Management > Rules : Read` privilege\r\n4. Create a user with that
role\r\n5. In another window, open Kibana with the newly created
user\r\n6. Check that the Stack Management > Alerts page renders
correctly, not\r\nshowing any missing 403 error
toasts","sha":"17fcaa5c8eb6cdff5f89a2fa28a20f42d020381f","branchLabelMapping":{"^v9.0.0$":"main","^v8.16.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix","Team:ResponseOps","v9.0.0","backport:prev-minor"],"title":"[ResponseOps][Alerting]
Fix stackAlerts plugin missing rac API auth
scope","number":193948,"url":"https://github.com/elastic/kibana/pull/193948","mergeCommit":{"message":"[ResponseOps][Alerting]
Fix stackAlerts plugin missing rac API auth scope (#193948)\n\n##
Summary\r\n\r\nAdds the `['rac']` API access scope to the Stack Alerts
feature to\r\ncorrectly authenticate alerts API endpoints with the
`stackAlerts`\r\npermission.\r\nAlso adds a dedicated API integration
test for the impacted endpoint and\r\npermission set.\r\n\r\n## Release
note\r\n\r\nFix Stack Alerts feature API access control\r\n\r\n## To
verify\r\n\r\n1. Create rules that fire alerts in Stack management\r\n2.
Wait for alerts to be created\r\n3. Create a role with only `Stack
Management > Rules : Read` privilege\r\n4. Create a user with that
role\r\n5. In another window, open Kibana with the newly created
user\r\n6. Check that the Stack Management > Alerts page renders
correctly, not\r\nshowing any missing 403 error
toasts","sha":"17fcaa5c8eb6cdff5f89a2fa28a20f42d020381f"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/193948","number":193948,"mergeCommit":{"message":"[ResponseOps][Alerting]
Fix stackAlerts plugin missing rac API auth scope (#193948)\n\n##
Summary\r\n\r\nAdds the `['rac']` API access scope to the Stack Alerts
feature to\r\ncorrectly authenticate alerts API endpoints with the
`stackAlerts`\r\npermission.\r\nAlso adds a dedicated API integration
test for the impacted endpoint and\r\npermission set.\r\n\r\n## Release
note\r\n\r\nFix Stack Alerts feature API access control\r\n\r\n## To
verify\r\n\r\n1. Create rules that fire alerts in Stack management\r\n2.
Wait for alerts to be created\r\n3. Create a role with only `Stack
Management > Rules : Read` privilege\r\n4. Create a user with that
role\r\n5. In another window, open Kibana with the newly created
user\r\n6. Check that the Stack Management > Alerts page renders
correctly, not\r\nshowing any missing 403 error
toasts","sha":"17fcaa5c8eb6cdff5f89a2fa28a20f42d020381f"}}]}]
BACKPORT-->

Co-authored-by: Umberto Pepato <[email protected]>
  • Loading branch information
kibanamachine and umbopepato authored Oct 7, 2024
1 parent 3ad02ed commit 821ddaa
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 26 deletions.
4 changes: 2 additions & 2 deletions x-pack/plugins/stack_alerts/server/feature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export const BUILT_IN_ALERTS_FEATURE: KibanaFeatureConfig = {
all: [],
read: [],
},
api: [],
api: ['rac'],
ui: [],
},
read: {
Expand Down Expand Up @@ -108,7 +108,7 @@ export const BUILT_IN_ALERTS_FEATURE: KibanaFeatureConfig = {
all: [],
read: [],
},
api: [],
api: ['rac'],
ui: [],
},
},
Expand Down
8 changes: 8 additions & 0 deletions x-pack/test/functional_with_es_ssl/config.base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,14 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) {
spaces: ['*'],
},
],
elasticsearch: {
indices: [
{
names: ['.alerts-*'],
privileges: ['read'],
},
],
},
},
only_actions_role: {
kibana: [
Expand Down
18 changes: 18 additions & 0 deletions x-pack/test/rule_registry/common/lib/authentication/roles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,23 @@ export const logsOnlyAllSpacesAll: Role = {
},
};

export const stackAlertsOnlyReadSpacesAll: Role = {
name: 'stack_alerts_only_read_spaces_all',
privileges: {
elasticsearch: {
indices: [],
},
kibana: [
{
feature: {
stackAlerts: ['read'],
},
spaces: ['*'],
},
],
},
};

export const stackAlertsOnlyAllSpacesAll: Role = {
name: 'stack_alerts_only_all_spaces_all',
privileges: {
Expand Down Expand Up @@ -511,6 +528,7 @@ export const allRoles = [
securitySolutionOnlyReadSpacesAll,
observabilityOnlyAllSpacesAll,
logsOnlyAllSpacesAll,
stackAlertsOnlyReadSpacesAll,
stackAlertsOnlyAllSpacesAll,
observabilityOnlyReadSpacesAll,
observabilityOnlyAllSpacesAllWithReadESIndices,
Expand Down
16 changes: 12 additions & 4 deletions x-pack/test/rule_registry/common/lib/authentication/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ import {
observabilityMinReadAlertsAllSpacesAll,
observabilityOnlyAllSpacesAllWithReadESIndices,
securitySolutionOnlyAllSpacesAllWithReadESIndices,
stackAlertsOnlyAllSpacesAll,
stackAlertsOnlyReadSpacesAll as stackAlertsOnlyReadSpacesAllRole,
stackAlertsOnlyAllSpacesAll as stackAlertsOnlyAllSpacesAllRole,
} from './roles';
import { User } from './types';

Expand Down Expand Up @@ -130,6 +131,12 @@ export const obsOnlyReadSpacesAll: User = {
roles: [observabilityOnlyReadSpacesAll.name],
};

export const stackAlertsOnlyReadSpacesAll: User = {
username: 'stack_alerts_only_read_spaces_all',
password: 'stack_alerts_only_read_spaces_all',
roles: [stackAlertsOnlyReadSpacesAllRole.name],
};

export const users = [
superUser,
secOnly,
Expand Down Expand Up @@ -177,10 +184,10 @@ export const logsOnlySpacesAll: User = {
roles: [logsOnlyAllSpacesAll.name],
};

export const stackAlertsOnlySpacesAll: User = {
export const stackAlertsOnlyAllSpacesAll: User = {
username: 'stack_alerts_only_all_spaces_all',
password: 'stack_alerts_only_all_spaces_all',
roles: [stackAlertsOnlyAllSpacesAll.name],
roles: [stackAlertsOnlyAllSpacesAllRole.name],
};

export const obsOnlySpacesAllEsRead: User = {
Expand Down Expand Up @@ -297,7 +304,8 @@ export const allUsers = [
secOnlyReadSpacesAll,
obsOnlySpacesAll,
logsOnlySpacesAll,
stackAlertsOnlySpacesAll,
stackAlertsOnlyReadSpacesAll,
stackAlertsOnlyAllSpacesAll,
obsSecSpacesAll,
obsSecReadSpacesAll,
obsMinReadAlertsRead,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@

import expect from '@kbn/expect';

import { superUser, obsOnlySpacesAll, secOnlyRead } from '../../../common/lib/authentication/users';
import {
superUser,
obsOnlySpacesAll,
secOnlyRead,
stackAlertsOnlyReadSpacesAll,
} from '../../../common/lib/authentication/users';
import type { User } from '../../../common/lib/authentication/types';
import { FtrProviderContext } from '../../../common/ftr_provider_context';
import { getSpaceUrlPrefix } from '../../../common/lib/authentication/spaces';
Expand All @@ -22,27 +27,19 @@ export default ({ getService }: FtrProviderContext) => {
const SPACE1 = 'space1';
const APM_ALERT_INDEX = '.alerts-observability.apm.alerts-default';
const SECURITY_SOLUTION_ALERT_INDEX = '.alerts-security.alerts';
const STACK_ALERT_INDEX = '.alerts-stack.alerts-default';

const getAPMIndexName = async (user: User, space: string, expectedStatusCode: number = 200) => {
const resp = await supertestWithoutAuth
.get(`${getSpaceUrlPrefix(space)}${ALERTS_INDEX_URL}?features=apm`)
.auth(user.username, user.password)
.set('kbn-xsrf', 'true')
.expect(expectedStatusCode);
return resp.body.index_name as string[];
};

const getSecuritySolutionIndexName = async (
const getIndexName = async (
featureIds: string[],
user: User,
space: string,
expectedStatusCode: number = 200
) => {
const resp = await supertestWithoutAuth
.get(`${getSpaceUrlPrefix(space)}${ALERTS_INDEX_URL}?features=siem`)
.get(`${getSpaceUrlPrefix(space)}${ALERTS_INDEX_URL}?features=${featureIds.join(',')}`)
.auth(user.username, user.password)
.set('kbn-xsrf', 'true')
.expect(expectedStatusCode);

return resp.body.index_name as string[];
};

Expand All @@ -52,24 +49,33 @@ export default ({ getService }: FtrProviderContext) => {
});
describe('Users:', () => {
it(`${obsOnlySpacesAll.username} should be able to access the APM alert in ${SPACE1}`, async () => {
const indexNames = await getAPMIndexName(obsOnlySpacesAll, SPACE1);
const indexNames = await getIndexName(['apm'], obsOnlySpacesAll, SPACE1);
expect(indexNames.includes(APM_ALERT_INDEX)).to.eql(true); // assert this here so we can use constants in the dynamically-defined test cases below
});

it(`${superUser.username} should be able to access the APM alert in ${SPACE1}`, async () => {
const indexNames = await getAPMIndexName(superUser, SPACE1);
const indexNames = await getIndexName(['apm'], superUser, SPACE1);
expect(indexNames.includes(APM_ALERT_INDEX)).to.eql(true); // assert this here so we can use constants in the dynamically-defined test cases below
});

it(`${secOnlyRead.username} should NOT be able to access the APM alert in ${SPACE1}`, async () => {
const indexNames = await getAPMIndexName(secOnlyRead, SPACE1);
const indexNames = await getIndexName(['apm'], secOnlyRead, SPACE1);
expect(indexNames?.length).to.eql(0);
});

it(`${secOnlyRead.username} should be able to access the security solution alert in ${SPACE1}`, async () => {
const indexNames = await getSecuritySolutionIndexName(secOnlyRead, SPACE1);
const indexNames = await getIndexName(['siem'], secOnlyRead, SPACE1);
expect(indexNames.includes(`${SECURITY_SOLUTION_ALERT_INDEX}-${SPACE1}`)).to.eql(true); // assert this here so we can use constants in the dynamically-defined test cases below
});

it(`${stackAlertsOnlyReadSpacesAll.username} should be able to access the stack alert in ${SPACE1}`, async () => {
const indexNames = await getIndexName(
['stackAlerts'],
stackAlertsOnlyReadSpacesAll,
SPACE1
);
expect(indexNames.includes(STACK_ALERT_INDEX)).to.eql(true);
});
});
});
};
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
obsOnlySpacesAll,
logsOnlySpacesAll,
secOnlySpacesAllEsReadAll,
stackAlertsOnlySpacesAll,
stackAlertsOnlyAllSpacesAll,
superUser,
} from '../../../common/lib/authentication/users';

Expand Down Expand Up @@ -360,8 +360,8 @@ export default ({ getService }: FtrProviderContext) => {
const result = await secureBsearch.send<RuleRegistrySearchResponse>({
supertestWithoutAuth,
auth: {
username: stackAlertsOnlySpacesAll.username,
password: stackAlertsOnlySpacesAll.password,
username: stackAlertsOnlyAllSpacesAll.username,
password: stackAlertsOnlyAllSpacesAll.password,
},
referer: 'test',
kibanaVersion,
Expand Down

0 comments on commit 821ddaa

Please sign in to comment.