Skip to content

[EDR Workflows][Device Control] Trusted Devices validators#231888

Merged
szwarckonrad merged 146 commits intoelastic:mainfrom
szwarckonrad:device-control-validators
Aug 26, 2025
Merged

[EDR Workflows][Device Control] Trusted Devices validators#231888
szwarckonrad merged 146 commits intoelastic:mainfrom
szwarckonrad:device-control-validators

Conversation

@szwarckonrad
Copy link
Copy Markdown
Contributor

@szwarckonrad szwarckonrad commented Aug 14, 2025

Prerequisite #231167
Followup #232269

This PR implements server-side validation for trusted devices in the Kibana by extending the existing list plugin extension points system. The implementation follows established patterns from trusted apps but supports trusted device-specific requirements, including allowing both Windows and Mac OS types (unlike other artifact types that only support single OS per entry) and validating the 5 supported device fields (username, host, device ID, manufacturer, product ID). The changes include a new TrustedDeviceValidator class, integration across all 9 exception list handlers, and comprehensive API integration tests to ensure proper validation and authorization.

Key changes:

  • New TrustedDeviceValidator class extending BaseValidator with full space awareness
  • Updated all 9 list plugin extension point handlers to include trusted device validation
  • Added comprehensive integration tests covering unique trusted device validation requirements
  • Maintains consistency with existing artifact validation patterns while supporting device-specific schema

szwarckonrad and others added 30 commits July 22, 2025 13:02
szwarckonrad added a commit that referenced this pull request Aug 21, 2025
Prerequisite #230174
Followup #231888

This PR introduces trusted devices as a new artifact type in the
Security Solution, enabling device-based allow-listing for endpoint
security policies.

### Flow:
<details><summary>User enables Device Control in policy settings 🖼️
</summary>
<img width="985" height="356" alt="Screenshot 2025-08-11 at 12 53 59"
src="https://github.com/user-attachments/assets/6da861ca-4b78-4704-ab12-9bd7cc602d05"
/>
</details>
<details><summary>User adds Trusted Device that will add a whitelist
condition to otherwise block policy 🖼️ </summary>
<img width="1028" height="530" alt="Screenshot 2025-08-11 at 12 54 10"
src="https://github.com/user-attachments/assets/bb801d77-398f-43ff-963a-d91e1c2372f9"
/>
</details>
<details><summary>Artifact is being generated and can be viewed in Agent
policy 🖼️ </summary>
<img width="620" height="724" alt="Screenshot 2025-08-11 at 12 59 40"
src="https://github.com/user-attachments/assets/ac36b3ed-ac1e-4931-8441-d85945629417"
/>
</details>
<details><summary>Artifact can be decoded from index storage 🖼️
</summary>
<img width="658" height="684" alt="Screenshot 2025-08-11 at 12 57 38"
src="https://github.com/user-attachments/assets/5b6337dc-59e1-4598-8b37-196ece4af5c3"
/>
</details>
<details><summary>Artifact can be decoded from fleet server API 🖼️
</summary>
<img width="1253" height="368" alt="Screenshot 2025-08-12 at 12 02 21"
src="https://github.com/user-attachments/assets/80229167-25f3-4413-be4e-a127d99faa99"
/>
</details>


### New Functionality:
- **Trusted devices schema and types** - Complete validation schemas for
device identification fields (USERNAME, HOST, DEVICE_ID, MANUFACTURER,
PRODUCT_ID)
- **Artifact integration** - Trusted devices now build and distribute
alongside other artifact types (trusted apps, blocklists, etc.)
- **Feature flag gating** - Controlled rollout via `trustedDevices`
experimental feature
- **OS support** - Windows and macOS (Linux support planned for future)

### Key Components:
- **API schemas** - GET, POST, PUT request validation with proper field
restrictions
- **Manifest manager integration** - `buildTrustedDevicesArtifacts()`
method following established patterns
- **Artifact constants** - Support for
`endpoint-trusteddevicelist-{os}-v1` naming convention
- **Effect scopes** - Global and policy-specific device trust
configurations
- **Unit test coverage** - extended existing test coverage as well as
introduced new test files where needed

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
# Conflicts:
#	x-pack/solutions/security/plugins/security_solution/common/endpoint/types/index.ts
#	x-pack/solutions/security/plugins/security_solution/common/endpoint/types/trusted_devices.ts
@szwarckonrad szwarckonrad marked this pull request as ready for review August 22, 2025 07:51
@szwarckonrad szwarckonrad requested review from a team as code owners August 22, 2025 07:51
@szwarckonrad szwarckonrad requested a review from denar50 August 22, 2025 07:51
@elasticmachine
Copy link
Copy Markdown
Contributor

Pinging @elastic/security-defend-workflows (Team:Defend Workflows)

Copy link
Copy Markdown
Member

@csr csr left a comment

Choose a reason for hiding this comment

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

AppEx QA changes (roles.yaml file) LGTM

Copy link
Copy Markdown
Contributor

@denar50 denar50 left a comment

Choose a reason for hiding this comment

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

Code review only for files owned by @elastic/security-detection-engine. LGTM!

- feature_siemV3.endpoint_list_all
- feature_siemV3.global_artifact_management_all
- feature_siemV3.trusted_applications_all
- feature_siemV3.trusted_devices_all
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.

is this intentional here? if yes, do we want to add the new privilege only to endpoint_policy_manager?

return super.validateHasPrivilege('canReadTrustedDevices');
}

private async validateTrustedDevicesFeatureEnabled(): Promise<void> {
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.

nice, very thorough! 👏

Comment on lines +45 to +54
await expect(
trustedDeviceValidator.validatePreCreateItem(
item as unknown as CreateExceptionListItemOptions
)
).rejects.toThrow(EndpointArtifactExceptionValidationError);
await expect(
trustedDeviceValidator.validatePreCreateItem(
item as unknown as CreateExceptionListItemOptions
)
).rejects.toThrow('Trusted devices feature is not enabled');
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.

the two calls can be merged into one:

        await expect(
          trustedDeviceValidator.validatePreCreateItem(
            item as unknown as CreateExceptionListItemOptions
          )
        ).rejects.toThrow(
          new EndpointArtifactExceptionValidationError('Trusted devices feature is not enabled')
        );

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.

but... i guess this is not a test with a long life expectancy... so this is a nit :)

Copy link
Copy Markdown
Contributor

@paul-tavares paul-tavares left a comment

Choose a reason for hiding this comment

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

Left a few comment, but am approving as they seem minor (but perhaps required)

Comment on lines +114 to +120
validate: (osTypes: string[]) => {
const validOsTypes = [OperatingSystem.WINDOWS, OperatingSystem.MAC];
const invalidOs = osTypes.find((os) => !validOsTypes.includes(os as OperatingSystem));
return invalidOs
? `Unsupported OS type: ${invalidOs}. Only Windows and Mac are supported for trusted devices.`
: undefined;
},
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 don't think this is needed. The osTypes is already validating that only Windows and Mac can be used, so I don't think this code is ever hit if you try to use anything else.

Also - I tested this via API and it currently allows for duplicate values to be set - example: os_types: ["windows", "windows"]. Perhaps add a validation for that instead.

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.

Fixed - removed redundant OS validation and added duplicate prevention to reject entries like ["windows", "windows"]

* Override base validation to allow both Windows and Mac OS types for trusted devices
*/
protected async validateBasicData(item: ExceptionItemLikeOptions) {
const TrustedDeviceBasicDataSchema = schema.object(
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.

Maybe extract the Schema into a module const just like the other schemas?

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.

Extracted schema to TrustedDeviceBasicDataSchema.

Comment on lines +48 to +65
const anEndpointArtifactError = (res: { body: { message: string } }) => {
expect(res.body.message).to.match(/EndpointArtifactError/);
};
const aValidationError = (res: { body: { message: string } }) => {
// Match either EndpointArtifactError or OpenAPI validation errors
expect(res.body.message).to.match(/(EndpointArtifactError|\[request body\])/);
};
const anErrorMessageWith = (
value: string | RegExp
): ((res: { body: { message: string } }) => void) => {
return (res) => {
if (value instanceof RegExp) {
expect(res.body.message).to.match(value);
} else {
expect(res.body.message).to.be(value);
}
};
};
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.

++1 on the function names here. Makes it very clear on intent when reading the assertions code below 👍

Comment on lines +101 to +104
name: schema.string({ minLength: 1, maxLength: 256 }),
description: schema.maybe(
schema.string({ minLength: 0, maxLength: 256, defaultValue: '' })
),
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.

Most of these properties are already validated at the Lists plugin level (here), so you might not need them unless you are trying to apply stricter validations.

Example: description is marked as optional here, but required at the lists plugin, so its not actually optional.

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.

Updated to use BasicEndpointExceptionDataSchema.extends() pattern, removing redundant validation while keeping trusted device-specific constraints

@szwarckonrad szwarckonrad enabled auto-merge (squash) August 26, 2025 10:19
@szwarckonrad szwarckonrad merged commit 136fb6d into elastic:main Aug 26, 2025
12 checks passed
@elasticmachine
Copy link
Copy Markdown
Contributor

💚 Build Succeeded

Metrics [docs]

✅ unchanged

History

cc @szwarckonrad

qn895 pushed a commit to qn895/kibana that referenced this pull request Aug 26, 2025
…1167)

Prerequisite elastic#230174
Followup elastic#231888

This PR introduces trusted devices as a new artifact type in the
Security Solution, enabling device-based allow-listing for endpoint
security policies.

### Flow:
<details><summary>User enables Device Control in policy settings 🖼️
</summary>
<img width="985" height="356" alt="Screenshot 2025-08-11 at 12 53 59"
src="https://github.com/user-attachments/assets/6da861ca-4b78-4704-ab12-9bd7cc602d05"
/>
</details>
<details><summary>User adds Trusted Device that will add a whitelist
condition to otherwise block policy 🖼️ </summary>
<img width="1028" height="530" alt="Screenshot 2025-08-11 at 12 54 10"
src="https://github.com/user-attachments/assets/bb801d77-398f-43ff-963a-d91e1c2372f9"
/>
</details>
<details><summary>Artifact is being generated and can be viewed in Agent
policy 🖼️ </summary>
<img width="620" height="724" alt="Screenshot 2025-08-11 at 12 59 40"
src="https://github.com/user-attachments/assets/ac36b3ed-ac1e-4931-8441-d85945629417"
/>
</details>
<details><summary>Artifact can be decoded from index storage 🖼️
</summary>
<img width="658" height="684" alt="Screenshot 2025-08-11 at 12 57 38"
src="https://github.com/user-attachments/assets/5b6337dc-59e1-4598-8b37-196ece4af5c3"
/>
</details>
<details><summary>Artifact can be decoded from fleet server API 🖼️
</summary>
<img width="1253" height="368" alt="Screenshot 2025-08-12 at 12 02 21"
src="https://github.com/user-attachments/assets/80229167-25f3-4413-be4e-a127d99faa99"
/>
</details>


### New Functionality:
- **Trusted devices schema and types** - Complete validation schemas for
device identification fields (USERNAME, HOST, DEVICE_ID, MANUFACTURER,
PRODUCT_ID)
- **Artifact integration** - Trusted devices now build and distribute
alongside other artifact types (trusted apps, blocklists, etc.)
- **Feature flag gating** - Controlled rollout via `trustedDevices`
experimental feature
- **OS support** - Windows and macOS (Linux support planned for future)

### Key Components:
- **API schemas** - GET, POST, PUT request validation with proper field
restrictions
- **Manifest manager integration** - `buildTrustedDevicesArtifacts()`
method following established patterns
- **Artifact constants** - Support for
`endpoint-trusteddevicelist-{os}-v1` naming convention
- **Effect scopes** - Global and policy-specific device trust
configurations
- **Unit test coverage** - extended existing test coverage as well as
introduced new test files where needed

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
szwarckonrad added a commit that referenced this pull request Aug 28, 2025
…2269)

Prerequisite #231888
Followup #232374
This PR brings comprehensive Cypress test coverage to Trusted Devices,
mirroring the established Trusted Apps testing patterns. We implemented
full CRUD operations testing, RBAC permissions validation, and
serverless PLI/tier access controls.

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
qn895 pushed a commit to qn895/kibana that referenced this pull request Sep 2, 2025
…stic#232269)

Prerequisite elastic#231888
Followup elastic#232374
This PR brings comprehensive Cypress test coverage to Trusted Devices,
mirroring the established Trusted Apps testing patterns. We implemented
full CRUD operations testing, RBAC permissions validation, and
serverless PLI/tier access controls.

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:skip This PR does not require backporting release_note:skip Skip the PR/issue when compiling release notes Team:Defend Workflows “EDR Workflows” sub-team of Security Solution v9.2.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants