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

[Security Solution] Add missing Detections API OpenAPI specs #186764

Merged
merged 4 commits into from
Jul 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -9,4 +9,4 @@ export * from './create_index/create_index.gen';
export * from './delete_index/delete_index.gen';
export * from './read_alerts_index_exists/read_alerts_index_exists_route';
export * from './read_index/read_index.gen';
export * from './read_privileges/read_privileges_route';
export * from './read_privileges/read_privileges.gen';
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* 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: Read privileges API endpoint
* version: 2023-10-31
*/

import { z } from 'zod';

export type GetPrivilegesResponse = z.infer<typeof GetPrivilegesResponse>;
export const GetPrivilegesResponse = z.object({
is_authenticated: z.boolean(),
has_encryption_key: z.boolean(),
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
openapi: 3.0.0
info:
title: Read privileges API endpoint
version: '2023-10-31'
paths:
/api/detection_engine/privileges:
get:
x-labels: [serverless, ess]
operationId: GetPrivileges
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: I noticed a discrepancy in the naming between operation ids and file names and code. Operation ids are "get something" whereas in the code we have "read something". Why? Is "get something" a naming convention we're going to use for all our API endpoints in OAS?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's a good topic to tech time meeting. Since Detections API is most a RESTful API it focuses on data over actions on that data. It looks logical to have the same Get, Post, Put, Delete verbs instead of vague Read, Create and etc.

In this PR I place OpenAPI specs in existing folders to minimize the diff. I intend to perform renaming in a separate PR since it's a minor thing and won't impact functionality but the diff could be relatively large.

x-codegen-enabled: true
summary: Returns user privileges for the Kibana space
description: |
Retrieves whether or not the user is authenticated, and the user's Kibana
space and index privileges, which determine if the user can create an
index for the Elastic Security alerts generated by
detection engine rules.
tags:
- Privileges API
responses:
200:
description: Successful response
content:
application/json:
schema:
type: object
properties:
is_authenticated:
type: boolean
has_encryption_key:
type: boolean
required: [is_authenticated, has_encryption_key]
401:
description: Unsuccessful authentication response
content:
application/json:
schema:
$ref: '../../../model/error_responses.schema.yaml#/components/schemas/PlatformErrorResponse'
500:
description: Internal server error response
content:
application/json:
schema:
$ref: '../../../model/error_responses.schema.yaml#/components/schemas/SiemErrorResponse'

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,15 @@ export type BulkDeleteRulesRequestBodyInput = z.input<typeof BulkDeleteRulesRequ

export type BulkDeleteRulesResponse = z.infer<typeof BulkDeleteRulesResponse>;
export const BulkDeleteRulesResponse = BulkCrudRulesResponse;

export type BulkDeleteRulesPostRequestBody = z.infer<typeof BulkDeleteRulesPostRequestBody>;
Copy link
Contributor

Choose a reason for hiding this comment

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

We should use the DELETE and POST request and response types in the API route handler so the compiler will help us identify errors. Right now these appear to be unused.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added generated TS types as union to avoid code duplication.

export const BulkDeleteRulesPostRequestBody = z.array(
z.object({
id: RuleObjectId.optional(),
rule_id: RuleSignatureId.optional(),
})
);
export type BulkDeleteRulesPostRequestBodyInput = z.input<typeof BulkDeleteRulesPostRequestBody>;

export type BulkDeleteRulesPostResponse = z.infer<typeof BulkDeleteRulesPostResponse>;
export const BulkDeleteRulesPostResponse = BulkCrudRulesResponse;
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,73 @@ paths:
application/json:
schema:
$ref: '../response_schema.schema.yaml#/components/schemas/BulkCrudRulesResponse'
400:
description: Invalid input data response
content:
application/json:
schema:
oneOf:
- $ref: '../../../model/error_responses.schema.yaml#/components/schemas/PlatformErrorResponse'
- $ref: '../../../model/error_responses.schema.yaml#/components/schemas/SiemErrorResponse'
401:
description: Unsuccessful authentication response
content:
application/json:
schema:
$ref: '../../../model/error_responses.schema.yaml#/components/schemas/PlatformErrorResponse'
500:
description: Internal server error response
content:
application/json:
schema:
$ref: '../../../model/error_responses.schema.yaml#/components/schemas/SiemErrorResponse'

post:
x-labels: [ess]
x-codegen-enabled: true
operationId: BulkDeleteRulesPost
deprecated: true
description: Deletes multiple rules.
tags:
- Bulk API
requestBody:
description: A JSON array of `id` or `rule_id` fields of the rules you want to delete.
required: true
content:
application/json:
schema:
type: array
items:
type: object
properties:
id:
$ref: '../../../model/rule_schema/common_attributes.schema.yaml#/components/schemas/RuleObjectId'
rule_id:
$ref: '../../../model/rule_schema/common_attributes.schema.yaml#/components/schemas/RuleSignatureId'
responses:
200:
description: Indicates a successful call.
content:
application/json:
schema:
$ref: '../response_schema.schema.yaml#/components/schemas/BulkCrudRulesResponse'
400:
description: Invalid input data response
content:
application/json:
schema:
oneOf:
- $ref: '../../../model/error_responses.schema.yaml#/components/schemas/PlatformErrorResponse'
- $ref: '../../../model/error_responses.schema.yaml#/components/schemas/SiemErrorResponse'
401:
description: Unsuccessful authentication response
content:
application/json:
schema:
$ref: '../../../model/error_responses.schema.yaml#/components/schemas/PlatformErrorResponse'
500:
description: Internal server error response
content:
application/json:
schema:
$ref: '../../../model/error_responses.schema.yaml#/components/schemas/SiemErrorResponse'
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
* 2.0.
*/

export * from './preview_rules_route';
export * from './rule_preview.gen';

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* 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: Rule preview API endpoint
* version: 2023-10-31
*/

import { z } from 'zod';

import {
EqlRuleCreateProps,
QueryRuleCreateProps,
SavedQueryRuleCreateProps,
ThresholdRuleCreateProps,
ThreatMatchRuleCreateProps,
MachineLearningRuleCreateProps,
NewTermsRuleCreateProps,
EsqlRuleCreateProps,
} from '../model/rule_schema/rule_schemas.gen';
import { NonEmptyString } from '../../model/primitives.gen';

export type RulePreviewParams = z.infer<typeof RulePreviewParams>;
export const RulePreviewParams = z.object({
invocationCount: z.number().int(),
timeframeEnd: z.string().datetime(),
});

export type RulePreviewLogs = z.infer<typeof RulePreviewLogs>;
export const RulePreviewLogs = z.object({
errors: z.array(NonEmptyString),
warnings: z.array(NonEmptyString),
/**
* Execution duration in milliseconds
*/
duration: z.number().int(),
startedAt: NonEmptyString.optional(),
});

export type RulePreviewRequestBody = z.infer<typeof RulePreviewRequestBody>;
export const RulePreviewRequestBody = z.discriminatedUnion('type', [
EqlRuleCreateProps.merge(RulePreviewParams),
QueryRuleCreateProps.merge(RulePreviewParams),
SavedQueryRuleCreateProps.merge(RulePreviewParams),
ThresholdRuleCreateProps.merge(RulePreviewParams),
ThreatMatchRuleCreateProps.merge(RulePreviewParams),
MachineLearningRuleCreateProps.merge(RulePreviewParams),
NewTermsRuleCreateProps.merge(RulePreviewParams),
EsqlRuleCreateProps.merge(RulePreviewParams),
]);
export type RulePreviewRequestBodyInput = z.input<typeof RulePreviewRequestBody>;

export type RulePreviewResponse = z.infer<typeof RulePreviewResponse>;
export const RulePreviewResponse = z.object({
logs: z.array(RulePreviewLogs),
previewId: NonEmptyString.optional(),
isAborted: z.boolean().optional(),
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
openapi: 3.0.0
info:
title: Rule preview API endpoint
version: '2023-10-31'
paths:
/api/detection_engine/rules/preview:
post:
x-labels: [serverless, ess]
operationId: RulePreview
x-codegen-enabled: true
summary: Preview rule alerts generated on specified time range
tags:
- Rule preview API
requestBody:
description: An object containing tags to add or remove and alert ids the changes will be applied
required: true
content:
application/json:
schema:
discriminator:
propertyName: type
anyOf:
- allOf:
- $ref: '../model/rule_schema/rule_schemas.schema.yaml#/components/schemas/EqlRuleCreateProps'
- $ref: '#/components/schemas/RulePreviewParams'
- allOf:
- $ref: '../model/rule_schema/rule_schemas.schema.yaml#/components/schemas/QueryRuleCreateProps'
- $ref: '#/components/schemas/RulePreviewParams'
- allOf:
- $ref: '../model/rule_schema/rule_schemas.schema.yaml#/components/schemas/SavedQueryRuleCreateProps'
- $ref: '#/components/schemas/RulePreviewParams'
- allOf:
- $ref: '../model/rule_schema/rule_schemas.schema.yaml#/components/schemas/ThresholdRuleCreateProps'
- $ref: '#/components/schemas/RulePreviewParams'
- allOf:
- $ref: '../model/rule_schema/rule_schemas.schema.yaml#/components/schemas/ThreatMatchRuleCreateProps'
- $ref: '#/components/schemas/RulePreviewParams'
- allOf:
- $ref: '../model/rule_schema/rule_schemas.schema.yaml#/components/schemas/MachineLearningRuleCreateProps'
- $ref: '#/components/schemas/RulePreviewParams'
- allOf:
- $ref: '../model/rule_schema/rule_schemas.schema.yaml#/components/schemas/NewTermsRuleCreateProps'
- $ref: '#/components/schemas/RulePreviewParams'
- allOf:
- $ref: '../model/rule_schema/rule_schemas.schema.yaml#/components/schemas/EsqlRuleCreateProps'
- $ref: '#/components/schemas/RulePreviewParams'
responses:
200:
description: Successful response
content:
application/json:
schema:
type: object
properties:
logs:
type: array
items:
$ref: '#/components/schemas/RulePreviewLogs'
previewId:
$ref: '../../model/primitives.schema.yaml#/components/schemas/NonEmptyString'
isAborted:
type: boolean
required: [logs]
400:
description: Invalid input data response
content:
application/json:
schema:
oneOf:
- $ref: '../../../model/error_responses.schema.yaml#/components/schemas/PlatformErrorResponse'
- $ref: '../../../model/error_responses.schema.yaml#/components/schemas/SiemErrorResponse'
401:
description: Unsuccessful authentication response
content:
application/json:
schema:
$ref: '../../../model/error_responses.schema.yaml#/components/schemas/PlatformErrorResponse'
500:
description: Internal server error response
content:
application/json:
schema:
$ref: '../../../model/error_responses.schema.yaml#/components/schemas/SiemErrorResponse'

components:
schemas:
RulePreviewParams:
type: object
properties:
invocationCount:
type: integer
timeframeEnd:
type: string
format: date-time
required: [invocationCount, timeframeEnd]

RulePreviewLogs:
type: object
properties:
errors:
type: array
items:
$ref: '../../model/primitives.schema.yaml#/components/schemas/NonEmptyString'
warnings:
type: array
items:
$ref: '../../model/primitives.schema.yaml#/components/schemas/NonEmptyString'
duration:
type: integer
description: Execution duration in milliseconds
startedAt:
$ref: '../../model/primitives.schema.yaml#/components/schemas/NonEmptyString'
required:
- errors
- warnings
- duration
Loading