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

[ResponseOps] Granular Connector RBAC #203503

Merged
merged 59 commits into from
Jan 6, 2025
Merged
Show file tree
Hide file tree
Changes from 47 commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
36a8907
Adding EDR feature privilege
doakalexi Oct 22, 2024
fdf7212
Updating the ui
doakalexi Oct 23, 2024
5384fa9
Rename to action instead of connector
doakalexi Oct 23, 2024
96ccb6d
Fix boolean
doakalexi Oct 23, 2024
c274951
Removing changes from email connector
doakalexi Oct 23, 2024
4f29da8
Updating canExecute
doakalexi Oct 23, 2024
ef4ba21
Merge branch 'main' into poc/connector-rbac
doakalexi Oct 23, 2024
5b79db1
Merge branch 'main' of github.com:elastic/kibana into poc/connector-rbac
doakalexi Nov 19, 2024
30c7260
Fixing a bad change from merge conflicts
doakalexi Nov 19, 2024
3e5f43f
Update EDR connectors to only allow testing for one sub action
doakalexi Nov 22, 2024
394a8af
Adding validation to rule creation
doakalexi Dec 3, 2024
a5cefc0
Merge branch 'main' of github.com:elastic/kibana into poc/connector-rbac
doakalexi Dec 3, 2024
613381a
Removing changes from merge conflicts
doakalexi Dec 3, 2024
6403e6b
Adding api key info to the event log
doakalexi Dec 3, 2024
a2d2079
Removing some changes that arent needed
doakalexi Dec 4, 2024
372012a
Removing consumer
doakalexi Dec 4, 2024
243cacc
Adding back rbac
doakalexi Dec 4, 2024
bf19980
Fixing typo
doakalexi Dec 5, 2024
be23b06
Merge branch 'main' of github.com:elastic/kibana into poc/connector-rbac
doakalexi Dec 9, 2024
5a7b3dd
Creating a new sub-feature field in the connector type
doakalexi Dec 9, 2024
7b34ca5
Adding back the api key
doakalexi Dec 10, 2024
68dc60f
Adding tests
doakalexi Dec 11, 2024
3830696
Removing api key code
doakalexi Dec 12, 2024
f7c006d
Adding functional tests
doakalexi Dec 12, 2024
886abec
Merge branch 'main' of github.com:elastic/kibana into connector-rbac
doakalexi Dec 12, 2024
3e4853d
Updating the subfeaturetype
doakalexi Dec 12, 2024
e40c39a
Fixing lint
doakalexi Dec 12, 2024
cf0884a
[CI] Auto-commit changed files from 'node scripts/notice'
kibanamachine Dec 12, 2024
cf1b80c
Removing circular dependency
doakalexi Dec 13, 2024
524649b
Merge branch 'main' of github.com:elastic/kibana into connector-rbac
doakalexi Dec 13, 2024
68d725f
[CI] Auto-commit changed files from 'node scripts/notice'
kibanamachine Dec 13, 2024
8f11152
Merge branch 'main' of github.com:elastic/kibana into connector-rbac
doakalexi Dec 13, 2024
d29771b
Merge branch 'connector-rbac' of github.com:doakalexi/kibana into con…
doakalexi Dec 13, 2024
2fad33b
Removing from tsconfig
doakalexi Dec 13, 2024
cb380ea
Fixing type check failures
doakalexi Dec 13, 2024
36c03ab
Fixing type check again
doakalexi Dec 13, 2024
936cab9
Fixing test failures
doakalexi Dec 13, 2024
0903096
Merge branch 'main' into connector-rbac
doakalexi Dec 13, 2024
2151a50
Fixing update rule tests
doakalexi Dec 16, 2024
988484c
Removing UI changes
doakalexi Dec 16, 2024
cde862f
Merge branch 'connector-rbac' of github.com:doakalexi/kibana into con…
doakalexi Dec 16, 2024
71ba4f9
Merge branch 'main' into connector-rbac
doakalexi Dec 16, 2024
923fc9a
Fixing bulk edit test
doakalexi Dec 16, 2024
b60de78
Merge branch 'connector-rbac' of github.com:doakalexi/kibana into con…
doakalexi Dec 16, 2024
60b0f65
Merge branch 'main' into connector-rbac
doakalexi Dec 16, 2024
11ad095
Fixing ai assistant privileges tests
doakalexi Dec 16, 2024
12a0c82
Merge branch 'connector-rbac' of github.com:doakalexi/kibana into con…
doakalexi Dec 16, 2024
f62d3e8
Removing so from subfeature
doakalexi Dec 19, 2024
83203e5
Merge branch 'main' into connector-rbac
doakalexi Dec 19, 2024
09f56a5
Merge branch 'main' of github.com:elastic/kibana into connector-rbac
doakalexi Dec 19, 2024
d12aa20
Merge branch 'connector-rbac' of github.com:doakalexi/kibana into con…
doakalexi Dec 19, 2024
7d000b3
Merge branch 'main' into connector-rbac
doakalexi Dec 26, 2024
a0a14ac
Merge branch 'main' of github.com:elastic/kibana into connector-rbac
doakalexi Dec 30, 2024
be33125
Merge branch 'main' into connector-rbac
doakalexi Jan 2, 2025
aa216e6
Renaming from PR feedback
doakalexi Jan 6, 2025
b1701a9
Merge branch 'main' into connector-rbac
doakalexi Jan 6, 2025
c8754b9
Fixing test failure
doakalexi Jan 6, 2025
6855741
Merge branch 'connector-rbac' of github.com:doakalexi/kibana into con…
doakalexi Jan 6, 2025
66103c8
Fixing test failure
doakalexi Jan 6, 2025
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
6 changes: 6 additions & 0 deletions packages/kbn-actions-types/action_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@

import type { LicenseType } from '@kbn/licensing-plugin/common/types';

export enum SUB_FEATURE_TYPE {
edr,
}
export type SubFeatureType = keyof typeof SUB_FEATURE_TYPE;

export interface ActionType {
id: string;
name: string;
Expand All @@ -18,4 +23,5 @@ export interface ActionType {
minimumLicenseRequired: LicenseType;
supportedFeatureIds: string[];
isSystemActionType: boolean;
subFeatureType?: SubFeatureType;
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ describe('transformConnectorTypesResponse', () => {
minimum_license_required: 'basic',
supported_feature_ids: ['stackAlerts'],
is_system_action_type: true,
sub_feature_type: 'edr',
},
{
id: 'actionType2Id',
Expand All @@ -44,6 +45,7 @@ describe('transformConnectorTypesResponse', () => {
minimumLicenseRequired: 'basic',
supportedFeatureIds: ['stackAlerts'],
isSystemActionType: true,
subFeatureType: 'edr',
},
{
id: 'actionType2Id',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ const transformConnectorType: RewriteRequestCase<ActionType> = ({
minimum_license_required: minimumLicenseRequired,
supported_feature_ids: supportedFeatureIds,
is_system_action_type: isSystemActionType,
sub_feature_type: subFeatureType,
...res
}: AsApiContract<ActionType>) => ({
enabledInConfig,
enabledInLicense,
minimumLicenseRequired,
supportedFeatureIds,
isSystemActionType,
subFeatureType,
...res,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type { ComponentType, ReactNode } from 'react';
import type { RuleActionParam, ActionVariable } from '@kbn/alerting-types';
import { IconType, RecursivePartial } from '@elastic/eui';
import { PublicMethodsOf } from '@kbn/utility-types';
import { SubFeatureType } from '@kbn/actions-types';
import { TypeRegistry } from '../type_registry';
import { RuleFormParamsErrors } from './rule_types';

Expand Down Expand Up @@ -130,6 +131,7 @@ export interface ActionTypeModel<ActionConfig = any, ActionSecrets = any, Action
hideInUi?: boolean;
modalWidth?: number;
isSystemActionType?: boolean;
subFeatureType?: SubFeatureType;
}

export type ActionTypeRegistryContract<Connector = unknown, Params = unknown> = PublicMethodsOf<
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const mockActionTypes = [
minimumLicenseRequired: 'basic',
isSystemActionType: true,
supportedFeatureIds: ['generativeAI'],
subFeatureType: undefined,
} as ActionType,
{
id: '.bedrock',
Expand All @@ -28,6 +29,7 @@ export const mockActionTypes = [
minimumLicenseRequired: 'basic',
isSystemActionType: true,
supportedFeatureIds: ['generativeAI'],
subFeatureType: undefined,
} as ActionType,
{
id: '.gemini',
Expand All @@ -38,6 +40,7 @@ export const mockActionTypes = [
minimumLicenseRequired: 'basic',
isSystemActionType: true,
supportedFeatureIds: ['generativeAI'],
subFeatureType: undefined,
} as ActionType,
];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,6 @@ import {
} from '@kbn/core/server';
import { mapValues } from 'lodash';
import { i18n } from '@kbn/i18n';
import {
CONNECTOR_TOKEN_SAVED_OBJECT_TYPE,
ACTION_SAVED_OBJECT_TYPE,
ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE,
} from '@kbn/actions-plugin/server/constants/saved_objects';
import { KibanaFeatureScope } from '@kbn/features-plugin/common';
import { OBSERVABILITY_AI_ASSISTANT_FEATURE_ID } from '../common/feature';
import type { ObservabilityAIAssistantConfig } from './config';
Expand Down Expand Up @@ -80,11 +75,7 @@ export class ObservabilityAIAssistantPlugin
api: [OBSERVABILITY_AI_ASSISTANT_FEATURE_ID, 'ai_assistant', 'manage_llm_product_doc'],
catalogue: [OBSERVABILITY_AI_ASSISTANT_FEATURE_ID],
savedObject: {
all: [
ACTION_SAVED_OBJECT_TYPE,
ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE,
CONNECTOR_TOKEN_SAVED_OBJECT_TYPE,
],
all: [],
Copy link
Member

Choose a reason for hiding this comment

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

question: What does this change mean for users who previously had the Observability AI Assistant all privilege? Will users with this privilege still be able to do everything they could before this change? Do we have any functional/api integration tests for this functionality?

Copy link
Contributor Author

@doakalexi doakalexi Dec 19, 2024

Choose a reason for hiding this comment

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

Thanks for asking! I should have left a note about the changes.

I removed this code because this test, Observability AI Assistant Functional tests feature_controls/assistant_security.spec.ts ai assistant privileges no actions privileges loads conversations UI with connector error message, was failing in x-pack/test/observability_ai_assistant_functional/tests/feature_controls/assistant_security.spec·ts. The test is checking that the user see's an error in the UI when they don't have actions privileges.

In the PR I removed a check in the actions authorization code with bidirectional connectors that would return an execute-basic privilege, and this change is what caused the test to fail. We think this happened bc the Observability AI Assistant was granting actions privileges through the SO types listed above. I removed them, bc based on the test I don't think that is expected behavior. I think everything should function the same, bc you need both Observability AI Assistant privileges and Actions privileges. cc @mikecote

Copy link
Member

Choose a reason for hiding this comment

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

Okay, thanks for clarifying this. That sounds plausible to me, as I can’t think of any reasonable use case where a feature completely unrelated to the Actions feature would need to grant direct access to the underlying Actions & Connectors SOs without requiring user to have proper Actions privileges. However, when it comes to AI assistants, I can never be 100% certain, and I assume the Obs AI Assistant team will need to validate our understanding 🙂

Copy link
Member

Choose a reason for hiding this comment

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

Indeed this came up before (https://elastic.slack.com/archives/CHSSGF015/p1692709333499069?thread_ts=1692299953.427369&cid=CHSSGF015), I've neglected to fix this, so fine with this change, but is this not a breaking change to users?

Copy link
Contributor Author

@doakalexi doakalexi Dec 30, 2024

Choose a reason for hiding this comment

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

I don't think so, I tested locally and it looks like the UI functions the same, it's showing an error that you need the actions and connectors privileges when you don't have it which is the same as the test above was expecting.
Screenshot 2024-12-30 at 12 30 15 PM

I can add a tooltip to the obs ai assistant feature privilege to help indicate that there is a dependency.

Screenshot 2024-12-30 at 11 53 55 AM

read: [],
},
ui: [aiAssistantCapabilities.show],
Expand Down
15 changes: 15 additions & 0 deletions x-pack/plugins/actions/common/connector_feature_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ export const SecurityConnectorFeatureId = 'siem';
export const GenerativeAIForSecurityConnectorFeatureId = 'generativeAIForSecurity';
export const GenerativeAIForObservabilityConnectorFeatureId = 'generativeAIForObservability';
export const GenerativeAIForSearchPlaygroundConnectorFeatureId = 'generativeAIForSearchPlayground';
export const EdrConnectorFeatureId = 'edr';

const compatibilityEdr = i18n.translate(
'xpack.actions.availableConnectorFeatures.compatibility.edr',
{
defaultMessage: 'Endpoint Security',
}
);

const compatibilityGenerativeAIForSecurity = i18n.translate(
'xpack.actions.availableConnectorFeatures.compatibility.generativeAIForSecurity',
Expand Down Expand Up @@ -120,6 +128,12 @@ export const GenerativeAIForSearchPlaygroundFeature: ConnectorFeatureConfig = {
compatibility: compatibilityGenerativeAIForSearchPlayground,
};

export const EdrConnectorFeature: ConnectorFeatureConfig = {
id: EdrConnectorFeatureId,
name: compatibilityEdr,
compatibility: compatibilityEdr,
};

const AllAvailableConnectorFeatures = {
[AlertingConnectorFeature.id]: AlertingConnectorFeature,
[CasesConnectorFeature.id]: CasesConnectorFeature,
Expand All @@ -128,6 +142,7 @@ const AllAvailableConnectorFeatures = {
[GenerativeAIForSecurityFeature.id]: GenerativeAIForSecurityFeature,
[GenerativeAIForObservabilityFeature.id]: GenerativeAIForObservabilityFeature,
[GenerativeAIForSearchPlaygroundFeature.id]: GenerativeAIForSearchPlaygroundFeature,
[EdrConnectorFeature.id]: EdrConnectorFeature,
};

export function areValidFeatures(ids: string[]) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,13 @@ export const connectorTypesResponseSchema = schema.object({
is_system_action_type: schema.boolean({
meta: { description: 'Indicates whether the action is a system action.' },
}),
sub_feature_type: schema.maybe(
schema.oneOf([schema.literal('edr')], {
meta: {
description: 'Indicates the sub-feature type the connector is grouped under.',
},
})
),
});

export const connectorExecuteResponseSchema = schema.object({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export interface ConnectorTypesResponse {
minimum_license_required: ConnectorTypesResponseSchemaType['minimum_license_required'];
supported_feature_ids: ConnectorTypesResponseSchemaType['supported_feature_ids'];
is_system_action_type: ConnectorTypesResponseSchemaType['is_system_action_type'];
sub_feature_type?: ConnectorTypesResponseSchemaType['sub_feature_type'];
}

type ConnectorExecuteResponseSchemaType = TypeOf<typeof connectorExecuteResponseSchema>;
Expand Down
5 changes: 5 additions & 0 deletions x-pack/plugins/actions/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* 2.0.
*/

import { SUB_FEATURE_TYPE } from '@kbn/actions-types';
import { LicenseType } from '@kbn/licensing-plugin/common/types';
import { TaskErrorSource } from '@kbn/task-manager-plugin/common';

Expand All @@ -15,6 +16,9 @@ export {
SecurityConnectorFeatureId,
GenerativeAIForSecurityConnectorFeatureId,
} from './connector_feature_config';

export type SubFeatureType = keyof typeof SUB_FEATURE_TYPE;

export interface ActionType {
id: string;
name: string;
Expand All @@ -24,6 +28,7 @@ export interface ActionType {
minimumLicenseRequired: LicenseType;
supportedFeatureIds: string[];
isSystemActionType: boolean;
subFeatureType?: SubFeatureType;
}

export enum InvalidEmailReason {
Expand Down
3 changes: 2 additions & 1 deletion x-pack/plugins/actions/server/action_type_registry.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ const createActionTypeRegistryMock = () => {
isActionExecutable: jest.fn(),
isSystemActionType: jest.fn(),
getUtils: jest.fn(),
getSystemActionKibanaPrivileges: jest.fn(),
getActionKibanaPrivileges: jest.fn(),
hasSubFeatureType: jest.fn(),
};
return mocked;
};
Expand Down
Loading