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

Add Security Monitoring rule test endpoint #1839

Merged
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
8 changes: 4 additions & 4 deletions .apigentools-info
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
"spec_versions": {
"v1": {
"apigentools_version": "1.6.6",
"regenerated": "2024-05-23 19:28:56.214593",
"spec_repo_commit": "b9b11fda"
"regenerated": "2024-05-28 16:29:32.536282",
"spec_repo_commit": "9445af96"
},
"v2": {
"apigentools_version": "1.6.6",
"regenerated": "2024-05-23 19:28:56.232566",
"spec_repo_commit": "b9b11fda"
"regenerated": "2024-05-28 16:29:32.555540",
"spec_repo_commit": "9445af96"
}
}
}
140 changes: 140 additions & 0 deletions .generator/schemas/v2/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17407,6 +17407,47 @@ components:
- GEO_DATA
- EVENT_COUNT
- NONE
SecurityMonitoringRuleQueryPayload:
description: Payload to test a rule query with the expected result.
properties:
expectedResult:
description: Expected result of the test.
example: true
type: boolean
index:
description: Index of the query under test.
example: 0
format: int64
minimum: 0
type: integer
payload:
$ref: '#/components/schemas/SecurityMonitoringRuleQueryPayloadData'
type: object
SecurityMonitoringRuleQueryPayloadData:
additionalProperties: {}
description: Payload used to test the rule query.
properties:
ddsource:
description: Source of the payload.
example: nginx
type: string
ddtags:
description: Tags associated with your data.
example: env:staging,version:5.1
type: string
hostname:
description: The name of the originating host of the log.
example: i-012345678
type: string
message:
description: The message of the payload.
example: 2019-11-19T14:37:58,995 INFO [process.name][20081] Hello World
type: string
service:
description: The name of the application or service generating the data.
example: payment
type: string
type: object
SecurityMonitoringRuleResponse:
description: Create a new rule.
oneOf:
Expand All @@ -17428,6 +17469,31 @@ components:
- MEDIUM
- HIGH
- CRITICAL
SecurityMonitoringRuleTestRequest:
description: Test the rule queries of a rule.
properties:
rule:
$ref: '#/components/schemas/SecurityMonitoringRuleCreatePayload'
ruleQueryPayloads:
description: Data payloads used to test rules query with the expected result.
items:
$ref: '#/components/schemas/SecurityMonitoringRuleQueryPayload'
type: array
type: object
SecurityMonitoringRuleTestResponse:
description: Result of the test of the rule queries.
properties:
results:
description: 'Assert results are returned in the same order as the rule
query payloads.

For each payload, it returns True if the result matched the expected result,

False otherwise.'
items:
type: boolean
type: array
type: object
SecurityMonitoringRuleThirdPartyOptions:
description: Options on third party rules.
properties:
Expand Down Expand Up @@ -32551,6 +32617,42 @@ paths:
tags:
- Security Monitoring
x-codegen-request-body-name: body
/api/v2/security_monitoring/rules/test:
post:
description: Test a rule.
operationId: TestSecurityMonitoringRule
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/SecurityMonitoringRuleTestRequest'
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/SecurityMonitoringRuleTestResponse'
description: OK
'400':
$ref: '#/components/responses/BadRequestResponse'
'401':
$ref: '#/components/responses/ConcurrentModificationResponse'
'403':
$ref: '#/components/responses/NotAuthorizedResponse'
'404':
$ref: '#/components/responses/NotFoundResponse'
'429':
$ref: '#/components/responses/TooManyRequestsResponse'
security:
- apiKeyAuth: []
appKeyAuth: []
- AuthZ:
- security_monitoring_rules_write
summary: Test a rule
tags:
- Security Monitoring
x-codegen-request-body-name: body
/api/v2/security_monitoring/rules/validation:
post:
description: Validate a detection rule.
Expand Down Expand Up @@ -32672,6 +32774,44 @@ paths:
tags:
- Security Monitoring
x-codegen-request-body-name: body
/api/v2/security_monitoring/rules/{rule_id}/test:
post:
description: Test an existing rule.
operationId: TestExistingSecurityMonitoringRule
parameters:
- $ref: '#/components/parameters/SecurityMonitoringRuleID'
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/SecurityMonitoringRuleTestRequest'
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/SecurityMonitoringRuleTestResponse'
description: OK
'400':
$ref: '#/components/responses/BadRequestResponse'
'401':
$ref: '#/components/responses/ConcurrentModificationResponse'
'403':
$ref: '#/components/responses/NotAuthorizedResponse'
'404':
$ref: '#/components/responses/NotFoundResponse'
'429':
$ref: '#/components/responses/TooManyRequestsResponse'
security:
- apiKeyAuth: []
appKeyAuth: []
- AuthZ:
- security_monitoring_rules_write
summary: Test an existing rule
tags:
- Security Monitoring
x-codegen-request-body-name: body
/api/v2/security_monitoring/signals:
get:
description: 'The list endpoint returns security signals that match a search
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2024-05-28T11:40:33.484Z

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Test an existing rule returns "OK" response

require "datadog_api_client"
api_instance = DatadogAPIClient::V2::SecurityMonitoringAPI.new

body = DatadogAPIClient::V2::SecurityMonitoringRuleTestRequest.new({
rule_query_payloads: [
DatadogAPIClient::V2::SecurityMonitoringRuleQueryPayload.new({
expected_result: true,
index: 0,
payload: DatadogAPIClient::V2::SecurityMonitoringRuleQueryPayloadData.new({
ddsource: "nginx",
ddtags: "env:staging,version:5.1",
hostname: "i-012345678",
message: "2019-11-19T14:37:58,995 INFO [process.name][20081] Hello World",
service: "payment",
}),
}),
],
})
p api_instance.test_existing_security_monitoring_rule("rule_id", body)
58 changes: 58 additions & 0 deletions examples/v2/security-monitoring/TestSecurityMonitoringRule.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Test a rule returns "OK" response

require "datadog_api_client"
api_instance = DatadogAPIClient::V2::SecurityMonitoringAPI.new

body = DatadogAPIClient::V2::SecurityMonitoringRuleTestRequest.new({
rule: DatadogAPIClient::V2::SecurityMonitoringStandardRuleCreatePayload.new({
cases: [
DatadogAPIClient::V2::SecurityMonitoringRuleCaseCreate.new({
name: "",
status: DatadogAPIClient::V2::SecurityMonitoringRuleSeverity::INFO,
notifications: [],
condition: "a > 0",
}),
],
has_extended_title: true,
is_enabled: true,
message: "My security monitoring rule message.",
name: "My security monitoring rule.",
options: DatadogAPIClient::V2::SecurityMonitoringRuleOptions.new({
decrease_criticality_based_on_env: false,
detection_method: DatadogAPIClient::V2::SecurityMonitoringRuleDetectionMethod::THRESHOLD,
evaluation_window: DatadogAPIClient::V2::SecurityMonitoringRuleEvaluationWindow::ZERO_MINUTES,
keep_alive: DatadogAPIClient::V2::SecurityMonitoringRuleKeepAlive::ZERO_MINUTES,
max_signal_duration: DatadogAPIClient::V2::SecurityMonitoringRuleMaxSignalDuration::ZERO_MINUTES,
}),
queries: [
DatadogAPIClient::V2::SecurityMonitoringStandardRuleQuery.new({
query: "source:source_here",
group_by_fields: [
"@userIdentity.assumed_role",
],
distinct_fields: [],
aggregation: DatadogAPIClient::V2::SecurityMonitoringRuleQueryAggregation::COUNT,
name: "",
}),
],
tags: [
"env:prod",
"team:security",
],
type: DatadogAPIClient::V2::SecurityMonitoringRuleTypeCreate::LOG_DETECTION,
}),
rule_query_payloads: [
DatadogAPIClient::V2::SecurityMonitoringRuleQueryPayload.new({
expected_result: true,
index: 0,
payload: DatadogAPIClient::V2::SecurityMonitoringRuleQueryPayloadData.new({
ddsource: "source_here",
ddtags: "env:staging,version:5.1",
hostname: "i-012345678",
message: "2019-11-19T14:37:58,995 INFO [process.name][20081] Hello World",
service: "payment",
}),
}),
],
})
p api_instance.test_security_monitoring_rule(body)
7 changes: 7 additions & 0 deletions features/scenarios_model_mapping.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1624,6 +1624,9 @@
"v2.CreateSecurityMonitoringRule" => {
"body" => "SecurityMonitoringRuleCreatePayload",
},
"v2.TestSecurityMonitoringRule" => {
"body" => "SecurityMonitoringRuleTestRequest",
},
"v2.ValidateSecurityMonitoringRule" => {
"body" => "SecurityMonitoringRuleCreatePayload",
},
Expand All @@ -1637,6 +1640,10 @@
"rule_id" => "String",
"body" => "SecurityMonitoringRuleUpdatePayload",
},
"v2.TestExistingSecurityMonitoringRule" => {
"rule_id" => "String",
"body" => "SecurityMonitoringRuleTestRequest",
},
"v2.ListSecurityMonitoringSignals" => {
"filter_query" => "String",
"filter_from" => "Time",
Expand Down
46 changes: 46 additions & 0 deletions features/v2/security_monitoring.feature
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,52 @@ Feature: Security Monitoring
When the request is sent
Then the response status is 200 OK

@skip @team:DataDog/k9-cloud-security-platform
Scenario: Test a rule returns "Bad Request" response
Given new "TestSecurityMonitoringRule" request
And body with value {"rule": {"cases": [], "filters": [{"action": "require"}], "hasExtendedTitle": true, "isEnabled": true, "message": "", "name": "My security monitoring rule.", "options": {"decreaseCriticalityBasedOnEnv": false, "detectionMethod": "threshold", "evaluationWindow": 0, "hardcodedEvaluatorType": "log4shell", "impossibleTravelOptions": {"baselineUserLocations": true}, "keepAlive": 0, "maxSignalDuration": 0, "newValueOptions": {"forgetAfter": 1, "learningDuration": 0, "learningMethod": "duration", "learningThreshold": 0}, "thirdPartyRuleOptions": {"defaultNotifications": [], "defaultStatus": "critical", "rootQueries": [{"groupByFields": [], "query": "source:cloudtrail"}]}}, "queries": [], "tags": ["env:prod", "team:security"], "thirdPartyCases": [], "type": "application_security"}, "ruleQueryPayloads": [{"expectedResult": true, "index": 0, "payload": {"ddsource": "nginx", "ddtags": "env:staging,version:5.1", "hostname": "i-012345678", "message": "2019-11-19T14:37:58,995 INFO [process.name][20081] Hello World", "service": "payment"}}]}
When the request is sent
Then the response status is 400 Bad Request

@skip @team:DataDog/k9-cloud-security-platform
Scenario: Test a rule returns "Not Found" response
Given new "TestSecurityMonitoringRule" request
And body with value {"rule": {"cases": [], "filters": [{"action": "require"}], "hasExtendedTitle": true, "isEnabled": true, "message": "", "name": "My security monitoring rule.", "options": {"decreaseCriticalityBasedOnEnv": false, "detectionMethod": "threshold", "evaluationWindow": 0, "hardcodedEvaluatorType": "log4shell", "impossibleTravelOptions": {"baselineUserLocations": true}, "keepAlive": 0, "maxSignalDuration": 0, "newValueOptions": {"forgetAfter": 1, "learningDuration": 0, "learningMethod": "duration", "learningThreshold": 0}, "thirdPartyRuleOptions": {"defaultNotifications": [], "defaultStatus": "critical", "rootQueries": [{"groupByFields": [], "query": "source:cloudtrail"}]}}, "queries": [], "tags": ["env:prod", "team:security"], "thirdPartyCases": [], "type": "application_security"}, "ruleQueryPayloads": [{"expectedResult": true, "index": 0, "payload": {"ddsource": "nginx", "ddtags": "env:staging,version:5.1", "hostname": "i-012345678", "message": "2019-11-19T14:37:58,995 INFO [process.name][20081] Hello World", "service": "payment"}}]}
When the request is sent
Then the response status is 404 Not Found

@skip-go @skip-java @skip-ruby @skip-typescript @team:DataDog/k9-cloud-security-platform
Scenario: Test a rule returns "OK" response
Given new "TestSecurityMonitoringRule" request
And body with value {"rule": {"cases": [{"name": "","status": "info","notifications": [],"condition": "a > 0"}],"hasExtendedTitle": true,"isEnabled": true,"message": "My security monitoring rule message.","name": "My security monitoring rule.","options": {"decreaseCriticalityBasedOnEnv": false,"detectionMethod": "threshold","evaluationWindow": 0,"keepAlive": 0,"maxSignalDuration": 0},"queries": [{"query": "source:source_here","groupByFields": ["@userIdentity.assumed_role"],"distinctFields": [],"aggregation": "count","name": ""}],"tags": ["env:prod", "team:security"],"type": "log_detection"}, "ruleQueryPayloads": [{"expectedResult": true,"index": 0,"payload": {"ddsource": "source_here","ddtags": "env:staging,version:5.1","hostname": "i-012345678","message": "2019-11-19T14:37:58,995 INFO [process.name][20081] Hello World","service": "payment","userIdentity": {"assumed_role" : "fake assumed_role"}}}]}
When the request is sent
Then the response status is 200 OK
And the response "results[0]" is equal to true

@skip @team:DataDog/k9-cloud-security-platform
Scenario: Test an existing rule returns "Bad Request" response
Given new "TestExistingSecurityMonitoringRule" request
And request contains "rule_id" parameter from "REPLACE.ME"
And body with value {"ruleQueryPayloads": [{"expectedResult": true, "index": 0, "payload": {"ddsource": "nginx", "ddtags": "env:staging,version:5.1", "hostname": "i-012345678", "message": "2019-11-19T14:37:58,995 INFO [process.name][20081] Hello World", "service": "payment"}}]}
When the request is sent
Then the response status is 400 Bad Request

@skip @team:DataDog/k9-cloud-security-platform
Scenario: Test an existing rule returns "Not Found" response
Given new "TestExistingSecurityMonitoringRule" request
And request contains "rule_id" parameter from "REPLACE.ME"
And body with value {"ruleQueryPayloads": [{"expectedResult": true, "index": 0, "payload": {"ddsource": "nginx", "ddtags": "env:staging,version:5.1", "hostname": "i-012345678", "message": "2019-11-19T14:37:58,995 INFO [process.name][20081] Hello World", "service": "payment"}}]}
When the request is sent
Then the response status is 404 Not Found

@skip @team:DataDog/k9-cloud-security-platform
Scenario: Test an existing rule returns "OK" response
Given new "TestExistingSecurityMonitoringRule" request
And request contains "rule_id" parameter from "REPLACE.ME"
And body with value {"ruleQueryPayloads": [{"expectedResult": true, "index": 0, "payload": {"ddsource": "nginx", "ddtags": "env:staging,version:5.1", "hostname": "i-012345678", "message": "2019-11-19T14:37:58,995 INFO [process.name][20081] Hello World", "service": "payment"}}]}
When the request is sent
Then the response status is 200 OK

@skip-validation @team:DataDog/k9-cloud-security-platform
Scenario: Update a cloud configuration rule's details returns "OK" response
Given new "UpdateSecurityMonitoringRule" request
Expand Down
Loading
Loading