Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Actions] System actions authorization #161341

Merged
merged 55 commits into from
Jul 20, 2023
Merged
Show file tree
Hide file tree
Changes from 53 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
1352e52
Add isSystemAction to ActionResult type and default it to false
cnasikas Jun 28, 2023
09b82f6
Disallow registering system actions
cnasikas Jun 28, 2023
dc1a2c8
Add test
cnasikas Jun 28, 2023
bb7e9a5
Fix alerting types
cnasikas Jun 28, 2023
774b389
Fix integration tests
cnasikas Jun 28, 2023
83ee747
Fix triggers_actions_ui types
cnasikas Jun 28, 2023
d2b8e67
Fix cases types
cnasikas Jun 28, 2023
31f1f39
Fix cases tests
cnasikas Jun 28, 2023
85ca6a4
Fix integration tests
cnasikas Jun 28, 2023
b070bd9
Fix cases tests
cnasikas Jun 28, 2023
a8e7143
Merge branch 'main' into system_actions_registration
kibanamachine Jun 29, 2023
b50a3e0
Fix types from other plugins
cnasikas Jun 29, 2023
ee5df7b
Merge branch 'system_actions_registration' of github.com:cnasikas/kib…
cnasikas Jun 29, 2023
1caf874
Rename preconfiguredConnectors to inMemoryConnectors
cnasikas Jun 29, 2023
2aabeed
Create system actions
cnasikas Jun 29, 2023
3cf469a
Prevent create/update/delete of system actions
cnasikas Jun 30, 2023
8c1246c
Fix types
cnasikas Jun 30, 2023
0d7aea1
Merge branch 'main' into load_system_actions_in_memory
cnasikas Jun 30, 2023
52ef0e5
Fix types
cnasikas Jun 30, 2023
d763161
Remove cases from basic
cnasikas Jul 1, 2023
5c3245e
Convert preconfigured to in-memory
cnasikas Jul 1, 2023
31bc750
Merge branch 'main' into load_system_actions_in_memory
cnasikas Jul 1, 2023
d35a7f9
Get in-memory connectors after they have been created in the route co…
cnasikas Jul 1, 2023
34ee2ab
Register test system action in integration tests
cnasikas Jul 1, 2023
86b279c
Add integration tests
cnasikas Jul 1, 2023
57b4d3a
Fix i18n
cnasikas Jul 2, 2023
a162163
Fix types
cnasikas Jul 2, 2023
2ea3c9c
Fix integration test
cnasikas Jul 2, 2023
7362b97
Fixes
cnasikas Jul 2, 2023
cbaeb1f
Merge branch 'main' into load_system_actions_in_memory
cnasikas Jul 3, 2023
a1b5d51
Filtered out system connectors in telemetry
cnasikas Jul 3, 2023
45c4690
Add the ability to pass additional privileges to the actions authoriz…
cnasikas Jul 3, 2023
2db46a0
Perform system actions RBAC
cnasikas Jul 3, 2023
9ebb327
Fix types and tests
cnasikas Jul 3, 2023
45f0265
Add unit tests
cnasikas Jul 4, 2023
e62faae
Add integration tests
cnasikas Jul 4, 2023
15da2b9
Add integration tests
cnasikas Jul 4, 2023
17d3c6e
Merge branch 'main' into system_actions_rbac
cnasikas Jul 6, 2023
637a6b3
Merge branch 'main' into system_actions_rbac
cnasikas Jul 7, 2023
eca005d
Fix tests
cnasikas Jul 8, 2023
0020ee9
Enhancements
cnasikas Jul 9, 2023
356432c
Pass params to system actions when getting kibana privileges
cnasikas Jul 9, 2023
4259f54
Fix integration tests
cnasikas Jul 9, 2023
c44f49d
Add integration tests for enqueue
cnasikas Jul 11, 2023
4035d11
Add integration tests for bulk_enqueue
cnasikas Jul 11, 2023
be7ec67
Add integration tests for spaces_only
cnasikas Jul 11, 2023
2c565b1
Fix integration tests
cnasikas Jul 11, 2023
a9e3bd5
Merge branch 'main' into system_actions_rbac
cnasikas Jul 11, 2023
72e9d72
Small improvements
cnasikas Jul 11, 2023
a8ea16b
Merge branch 'main' into system_actions_rbac
cnasikas Jul 13, 2023
dddcc8e
Do not allow setting kibana privileges if it is not a system action type
cnasikas Jul 13, 2023
8a9e449
Fix test
cnasikas Jul 13, 2023
1794087
Fix i18n
cnasikas Jul 13, 2023
0a07366
Merge branch 'main' into system_actions_rbac
cnasikas Jul 20, 2023
59cfda7
PR feedback
cnasikas Jul 20, 2023
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 @@ -19,6 +19,7 @@ const createActionTypeRegistryMock = () => {
isActionExecutable: jest.fn(),
isSystemActionType: jest.fn(),
getUtils: jest.fn(),
getSystemActionKibanaPrivileges: jest.fn(),
};
return mocked;
};
Expand Down
111 changes: 111 additions & 0 deletions x-pack/plugins/actions/server/action_type_registry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,29 @@ describe('actionTypeRegistry', () => {
})
).not.toThrow();
});

test('throws if the kibana privileges are defined but the action type is not a system action type', () => {
const actionTypeRegistry = new ActionTypeRegistry(actionTypeRegistryParams);

expect(() =>
actionTypeRegistry.register({
id: 'my-action-type',
name: 'My action type',
minimumLicenseRequired: 'basic',
supportedFeatureIds: ['alerting'],
getKibanaPrivileges: jest.fn(),
isSystemActionType: false,
validate: {
config: { schema: schema.object({}) },
secrets: { schema: schema.object({}) },
params: { schema: schema.object({}) },
},
executor,
})
).toThrowErrorMatchingInlineSnapshot(
`"Kibana privilege authorization is only supported for system action types"`
);
});
});

describe('get()', () => {
Expand Down Expand Up @@ -691,4 +714,92 @@ describe('actionTypeRegistry', () => {
expect(result).toBe(false);
});
});

describe('getSystemActionKibanaPrivileges()', () => {
it('should get the kibana privileges correctly for system actions', () => {
const registry = new ActionTypeRegistry(actionTypeRegistryParams);

registry.register({
id: '.cases',
name: 'Cases',
minimumLicenseRequired: 'platinum',
supportedFeatureIds: ['alerting'],
getKibanaPrivileges: () => ['test/create'],
validate: {
config: { schema: schema.object({}) },
secrets: { schema: schema.object({}) },
params: { schema: schema.object({}) },
},
isSystemActionType: true,
executor,
});

const result = registry.getSystemActionKibanaPrivileges('.cases');
expect(result).toEqual(['test/create']);
});

it('should return an empty array if the system action does not define any kibana privileges', () => {
const registry = new ActionTypeRegistry(actionTypeRegistryParams);

registry.register({
id: '.cases',
name: 'Cases',
minimumLicenseRequired: 'platinum',
supportedFeatureIds: ['alerting'],
validate: {
config: { schema: schema.object({}) },
secrets: { schema: schema.object({}) },
params: { schema: schema.object({}) },
},
isSystemActionType: true,
executor,
});

const result = registry.getSystemActionKibanaPrivileges('.cases');
expect(result).toEqual([]);
});

it('should return an empty array if the action type is not a system action', () => {
const registry = new ActionTypeRegistry(actionTypeRegistryParams);

registry.register({
id: 'foo',
name: 'Foo',
minimumLicenseRequired: 'basic',
supportedFeatureIds: ['alerting'],
validate: {
config: { schema: schema.object({}) },
secrets: { schema: schema.object({}) },
params: { schema: schema.object({}) },
},
executor,
});

const result = registry.getSystemActionKibanaPrivileges('foo');
expect(result).toEqual([]);
});

it('should pass the metadata correctly', () => {
const registry = new ActionTypeRegistry(actionTypeRegistryParams);
const getKibanaPrivileges = jest.fn().mockReturnValue(['test/create']);

registry.register({
id: '.cases',
name: 'Cases',
minimumLicenseRequired: 'platinum',
supportedFeatureIds: ['alerting'],
getKibanaPrivileges,
validate: {
config: { schema: schema.object({}) },
secrets: { schema: schema.object({}) },
params: { schema: schema.object({}) },
},
isSystemActionType: true,
executor,
});

registry.getSystemActionKibanaPrivileges('.cases', { foo: 'bar' });
expect(getKibanaPrivileges).toHaveBeenCalledWith({ metadata: { foo: 'bar' } });
});
});
});
25 changes: 25 additions & 0 deletions x-pack/plugins/actions/server/action_type_registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,22 @@ export class ActionTypeRegistry {
public isSystemActionType = (actionTypeId: string): boolean =>
Boolean(this.actionTypes.get(actionTypeId)?.isSystemActionType);

/**
* Returns the kibana privileges of a system action type
*/
public getSystemActionKibanaPrivileges(
actionTypeId: string,
metadata?: Record<string, unknown>
Copy link
Member Author

Choose a reason for hiding this comment

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

): string[] {
const actionType = this.actionTypes.get(actionTypeId);

if (!actionType?.isSystemActionType) {
return [];
}

return actionType?.getKibanaPrivileges?.({ metadata }) ?? [];
}

/**
* Registers an action type to the action type registry
*/
Expand Down Expand Up @@ -148,6 +164,15 @@ export class ActionTypeRegistry {
);
}

if (!actionType.isSystemActionType && actionType.getKibanaPrivileges) {
throw new Error(
i18n.translate('xpack.actions.actionTypeRegistry.register.invalidKibanaPrivileges', {
defaultMessage:
'Kibana privilege authorization is only supported for system action types',
})
);
}

const maxAttempts = this.actionsConfigUtils.getMaxAttempts({
actionTypeId: actionType.id,
actionTypeMaxAttempts: actionType.maxAttempts,
Expand Down
Loading