Skip to main content

Test Rule

Test a rule against sample log data or historical data without creating alerts.

Sample Log Test

Endpoint

POST /api/rules/{id}/test

Request Body

{
  "sample_log": {
    "EventID": 4625,
    "User": "admin",
    "SourceIP": "192.168.1.50",
    "@timestamp": "2024-01-15T10:30:00Z"
  }
}

Response

{
  "matches": true,
  "rule_id": "abc-123",
  "rule_title": "Failed Login Attempt",
  "matched_conditions": [
    {
      "selection": {
        "EventID": "4625"
      }
    }
  ]
}

Historical Test (Dry Run)

Test against real historical data in OpenSearch.

Endpoint

POST /api/rules/{id}/test/historical

Request Body

{
  "time_range": "1h",
  "limit": 100
}

Time Range Options

ValueDescription
1hLast 1 hour
6hLast 6 hours
1dLast 24 hours
7dLast 7 days

Response

{
  "rule_id": "abc-123",
  "rule_title": "Failed Login Attempt",
  "time_range": "1h",
  "matches": 42,
  "sample_matches": [
    {
      "timestamp": "2024-01-15T14:30:00Z",
      "source": {
        "ip": "192.168.1.50"
      },
      "user": {
        "name": "admin"
      }
    },
    {
      "timestamp": "2024-01-15T14:25:00Z",
      "source": {
        "ip": "192.168.1.51"
      },
      "user": {
        "name": "service_account"
      }
    }
  ]
}

Test Without Saving

Test YAML without saving to database:

Endpoint

POST /api/rules/test

Request Body

{
  "yaml_content": "title: Test Rule\n...",
  "sample_log": {...}
}
Useful for validating rule logic before creation.

Error Responses

400 Bad Request

{
  "detail": "Invalid sample log format"
}

422 Validation Error

{
  "detail": "Rule validation failed",
  "errors": [...]
}

503 Service Unavailable

{
  "detail": "OpenSearch unavailable for historical test"
}

Authentication

Requires JWT token with Analyst or Admin role.

Code Examples

Python - Sample Test

import requests

sample_log = {
    "EventID": 4625,
    "User": "admin",
    "SourceIP": "192.168.1.50",
    "@timestamp": "2024-01-15T10:30:00Z"
}

response = requests.post(
    f"{BASE_URL}/api/rules/abc-123/test",
    headers={
        "Authorization": f"Bearer {JWT_TOKEN}",
        "X-CSRF-Token": csrf_token
    },
    json={"sample_log": sample_log}
)

result = response.json()
if result["matches"]:
    print("Rule would match this log")
else:
    print("Rule would NOT match this log")

Python - Historical Test

response = requests.post(
    f"{BASE_URL}/api/rules/abc-123/test/historical",
    headers={
        "Authorization": f"Bearer {JWT_TOKEN}",
        "X-CSRF-Token": csrf_token
    },
    json={"time_range": "1d", "limit": 100}
)

result = response.json()
print(f"Found {result['matches']} matches in last 24 hours")

for match in result["sample_matches"][:5]:
    print(f"  - {match['timestamp']}: {match.get('user', {}).get('name', 'unknown')}")

JavaScript

// Sample log test
const response = await fetch(
  'https://chad.example.com/api/rules/abc-123/test',
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${jwtToken}`,
      'Content-Type': 'application/json',
      'X-CSRF-Token': csrfToken
    },
    body: JSON.stringify({
      sample_log: {
        EventID: 4625,
        User: 'admin'
      }
    })
  }
);

const result = await response.json();
console.log(`Matches: ${result.matches}`);