Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
d91c36f
[data] add endpoint opt-in status to reference dataset
gergoabraham Mar 22, 2026
65b207f
[api] add POST API to allow opting in
gergoabraham Mar 22, 2026
130a7a4
[api] add test coverage for POST api
gergoabraham Mar 22, 2026
3cc05d6
[api] add GET API to allow fetching opt-in status
gergoabraham Mar 23, 2026
a99ddc0
[docs] add api documentation
gergoabraham Mar 23, 2026
5e2e906
[api] remove manually created response type
gergoabraham Mar 23, 2026
88289fa
[ui] add callout component
gergoabraham Mar 24, 2026
41c6e06
[ui] add modal component
gergoabraham Mar 24, 2026
b5a1c8e
[ui] add initial behavior in `usePerPolicyOptIn`
gergoabraham Mar 24, 2026
bfdc38a
[ui] add new `callout` prop to artifact list page
gergoabraham Mar 24, 2026
9f4d87f
[ui] add unit test coverage
gergoabraham Mar 24, 2026
7d97b5a
[ui] RBAC: only admin can opt in
gergoabraham Mar 25, 2026
0664591
[ui] show opt-in menu action to user
gergoabraham Mar 25, 2026
9127f15
[e2e] add cypress happy-path test
gergoabraham Mar 25, 2026
fc92314
[e2e] perform opt-in in existing endpoint exceptions cy test
gergoabraham Mar 25, 2026
a897bea
[ui] hiding policy selector on endpoint exception form
gergoabraham Mar 25, 2026
eb3ea95
[ui] hiding policy assignment in policy details for endpoint exceptions
gergoabraham Mar 25, 2026
5f02fd9
[api] update create/update apis with opt-in status
gergoabraham Mar 26, 2026
82412cf
[api] update import api with opt-in status
gergoabraham Mar 26, 2026
ca628fb
[task] update ManifestManager with opt-in status
gergoabraham Mar 26, 2026
2165f67
[ui] hide "Add existing endpont exceptions" to rule checkbox based on…
gergoabraham Mar 27, 2026
018ee4c
[DE] do not evaluate endpoint exceptions based on opt-in status
gergoabraham Mar 27, 2026
81e24a7
[data] initialize opt-in status based on new deployment vs upgrade
gergoabraham Mar 27, 2026
9947fb8
[ui] do not show callouts on new deployments
gergoabraham Mar 27, 2026
c5bd1f8
[ui] show error to user when opt-in status cannot be fetched
gergoabraham Mar 27, 2026
fe9997a
[license] gate opt-in below platinum license
gergoabraham Mar 27, 2026
af8240e
fix floating promise lint issue
gergoabraham Mar 27, 2026
5e68004
Merge branch 'main' into per-policy-endpoint-exceptions-opt-in
gergoabraham Mar 30, 2026
f1e9dd6
[test] fix: no opt-in in basic license test
gergoabraham Mar 30, 2026
fb4c09d
[test] fix jest tests
gergoabraham Mar 30, 2026
1a80187
[test] fix endpoint exceptions cypress test
gergoabraham Mar 30, 2026
bfc3c44
[docs] hide api docs until FF is enabled
gergoabraham Mar 30, 2026
c09b717
[rbac] fix `admin` vs `superuser` for `serverless` vs `ess`
gergoabraham Mar 30, 2026
f1b4c5d
[ui] fix condition for showing callout
gergoabraham Mar 30, 2026
e9c1531
[test] move new utilities in existing `endpoint_artifact_services.ts`
gergoabraham Mar 30, 2026
681aadc
[data] store username and timestamp on opt-in
gergoabraham Mar 30, 2026
3e40722
[test] fix for serverless
gergoabraham Mar 30, 2026
4feb866
[task] optimize SO service usage
gergoabraham Mar 30, 2026
6c59790
[ui] typo change
gergoabraham Mar 30, 2026
adf803f
[chore] update imports
gergoabraham Mar 30, 2026
53185e4
[ui] do not call opt-in API with FF disabled
gergoabraham Mar 30, 2026
95f0db6
[ui] add doc link
gergoabraham Mar 30, 2026
b221241
type fix
gergoabraham Mar 30, 2026
0989562
[ui] remove toast from api request hook
gergoabraham Mar 30, 2026
49010a4
Merge branch 'main' into per-policy-endpoint-exceptions-opt-in
gergoabraham Mar 31, 2026
dd8cf08
[test] update endpoint list API tests
gergoabraham Mar 31, 2026
37a2094
[auth] fix `canReadAdminData` and `canWriteAdminData`
gergoabraham Mar 31, 2026
0c64ee5
[auth] simplification: reuse `hasAdminWrite`, get rid of `canOptInPer…
gergoabraham Mar 31, 2026
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 @@ -463,6 +463,7 @@ export const getDocLinks = ({ kibanaBranch, buildFlavor }: GetDocLinkOptions): D
installElasticDefend: `${ELASTIC_DOCS}solutions/security/configure-elastic-defend/install-elastic-defend`,
avcResults: `https://www.elastic.co/blog/elastic-security-av-comparatives-business-test`,
bidirectionalIntegrations: `${ELASTIC_DOCS}solutions/security/endpoint-response-actions/third-party-response-actions`,
endpointExceptions: `${ELASTIC_DOCS}solutions/security/manage-elastic-defend/elastic-endpoint-exceptions`,
trustedApps: `${ELASTIC_DOCS}solutions/security/manage-elastic-defend/trusted-applications`,
trustedDevices: `${ELASTIC_DOCS}solutions/security/manage-elastic-defend/trusted-devices`,
elasticAiFeatures: `${ELASTIC_DOCS}solutions/security/ai`,
Expand Down
1 change: 1 addition & 0 deletions src/platform/packages/shared/kbn-doc-links/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ export interface DocLinks {
readonly avcResults: string;
readonly bidirectionalIntegrations: string;
readonly thirdPartyLlmProviders: string;
readonly endpointExceptions: string;
readonly trustedApps: string;
readonly trustedDevices: string;
readonly elasticAiFeatures: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,18 @@ const securitySolutionApiServiceFactory = (supertest: SuperTest.Agent) => ({
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana');
},
getEndpointExceptionsPerPolicyOptIn(kibanaSpace: string = 'default') {
return supertest
.get(
getRouteUrlForSpace(
'/internal/api/endpoint/endpoint_exceptions_per_policy_opt_in',
kibanaSpace
)
)
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '1')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana');
},
getEndpointMetadataList(props: GetEndpointMetadataListProps, kibanaSpace: string = 'default') {
return supertest
.get(getRouteUrlForSpace('/api/endpoint/metadata', kibanaSpace))
Expand Down Expand Up @@ -328,6 +340,18 @@ const securitySolutionApiServiceFactory = (supertest: SuperTest.Agent) => ({
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
.query(props.query);
},
performEndpointExceptionsPerPolicyOptIn(kibanaSpace: string = 'default') {
return supertest
.post(
getRouteUrlForSpace(
'/internal/api/endpoint/endpoint_exceptions_per_policy_opt_in',
kibanaSpace
)
)
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '1')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana');
},
/**
* Run a script on a host. Currently supported only for some agent types.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

/*
* NOTICE: Do not edit this file manually.
* This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator.
*
* info:
* title: Endpoint Exceptions Per Policy Opt-In API
* version: 1
*/

import { z } from '@kbn/zod/v4';

export type GetEndpointExceptionsPerPolicyOptInResponse = z.infer<
typeof GetEndpointExceptionsPerPolicyOptInResponse
>;
export const GetEndpointExceptionsPerPolicyOptInResponse = z.object({
status: z.boolean(),
reason: z.enum(['newDeployment', 'userOptedIn']).optional(),
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
openapi: 3.0.0
info:
title: Endpoint Exceptions Per Policy Opt-In API
version: '1'
paths:
/internal/api/endpoint/endpoint_exceptions_per_policy_opt_in:
Comment thread
gergoabraham marked this conversation as resolved.
get:
summary: Retrieve endpoint exceptions per policy opt-in
operationId: GetEndpointExceptionsPerPolicyOptIn
x-codegen-enabled: true
x-labels: []
# TODO: When the feature flag `endpointExceptionsMovedUnderManagement` is enabled, remove empty `x-labels` and un-comment the line below.
# x-labels: [ ess, serverless ]
x-internal: true
responses:
'200':
description: OK
content:
application/json:
schema:
type: object
required:
- status
properties:
status:
type: boolean
reason:
type: string
enum: [newDeployment, userOptedIn]

post:
summary: Opt-in to endpoint exceptions per policy
operationId: PerformEndpointExceptionsPerPolicyOptIn
x-codegen-enabled: true
x-labels: []
# TODO: When the feature flag `endpointExceptionsMovedUnderManagement` is enabled, remove empty `x-labels` and un-comment the line below.
# x-labels: [ ess, serverless ]
x-internal: true
responses:
'200':
description: OK

Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ import type {
EndpointGetActionsStatusRequestQueryInput,
EndpointGetActionsStatusResponse,
} from './endpoint/actions/status/status.gen';
import type { GetEndpointExceptionsPerPolicyOptInResponse } from './endpoint/endpoint_exceptions_per_policy_opt_in/endpoint_exceptions_per_policy_opt_in.gen';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I guess we're using the ZOD schemas generated from API docs now? I though we were sticking with Kibana Schemas for our APIs

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

oh, yeah, i did not notice that the generated schemas are not used, although 27 of our API docs enabled x-codegen-enabled, and only 15 disabled it.

do we have a reason not to use these? if yes, i'll switch these to a hand-made schema, otherwise i think it is nice to have a single source of truth... especially if we have to write the API docs anyway

import type {
GetEndpointMetadataListRequestQueryInput,
GetEndpointMetadataListResponse,
Expand Down Expand Up @@ -1872,6 +1873,18 @@ finalize it.
})
.catch(catchAxiosErrorFormatAndThrow);
}
async getEndpointExceptionsPerPolicyOptIn() {
this.log.info(`${new Date().toISOString()} Calling API GetEndpointExceptionsPerPolicyOptIn`);
return this.kbnClient
.request<GetEndpointExceptionsPerPolicyOptInResponse>({
path: '/internal/api/endpoint/endpoint_exceptions_per_policy_opt_in',
headers: {
[ELASTIC_HTTP_VERSION_HEADER]: '1',
},
method: 'GET',
})
.catch(catchAxiosErrorFormatAndThrow);
}
async getEndpointMetadataList(props: GetEndpointMetadataListProps) {
this.log.info(`${new Date().toISOString()} Calling API GetEndpointMetadataList`);
return this.kbnClient
Expand Down Expand Up @@ -2653,6 +2666,20 @@ The difference between the `id` and `rule_id` is that the `id` is a unique rule
})
.catch(catchAxiosErrorFormatAndThrow);
}
async performEndpointExceptionsPerPolicyOptIn() {
this.log.info(
`${new Date().toISOString()} Calling API PerformEndpointExceptionsPerPolicyOptIn`
);
return this.kbnClient
.request({
path: '/internal/api/endpoint/endpoint_exceptions_per_policy_opt_in',
headers: {
[ELASTIC_HTTP_VERSION_HEADER]: '1',
},
method: 'POST',
})
.catch(catchAxiosErrorFormatAndThrow);
}
/**
* Apply a bulk action, such as bulk edit, duplicate, or delete, to multiple detection rules. The bulk action is applied to all rules that match the query or to the rules listed by their IDs.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ export const ENDPOINT_ERROR_CODES: Record<string, number> = {
export const ENDPOINT_FIELDS_SEARCH_STRATEGY = 'endpointFields';
export const ENDPOINT_SEARCH_STRATEGY = 'endpointSearchStrategy';

/** Endpoint Exceptions routes */
export const ENDPOINT_EXCEPTIONS_PER_POLICY_OPT_IN_ROUTE = `${BASE_INTERNAL_ENDPOINT_ROUTE}/endpoint_exceptions_per_policy_opt_in`;

/** Search strategy keys */
export const ENDPOINT_PACKAGE_POLICIES_STATS_STRATEGY = 'endpointPackagePoliciesStatsStrategy';

Expand Down
Loading
Loading