Skip to content

Commit e125cac

Browse files
authored
Merge pull request #182 from google/feature/case-management-methods
feat: added case management support
2 parents edc6a63 + 5263548 commit e125cac

15 files changed

Lines changed: 3265 additions & 77 deletions

CHANGELOG.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,28 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.37.0] - 2026-03-11
9+
### Added
10+
- Comprehensive case management functionality for Chronicle
11+
- `get_case()` - Retrieve single case details with optional field expansion
12+
- `list_cases()` - List cases with filtering, pagination, and sorting capabilities
13+
- `patch_case()` - Update case properties using partial updates
14+
- `merge_cases()` - Merge multiple cases into a single case
15+
- `get_cases()` - Legacy batch case retrieval for multiple case IDs
16+
- Bulk case operations for efficient case management
17+
- `execute_bulk_add_tag()` - Add tags to multiple cases
18+
- `execute_bulk_assign()` - Assign multiple cases to users
19+
- `execute_bulk_change_priority()` - Change priority for multiple cases
20+
- `execute_bulk_change_stage()` - Change stage for multiple cases
21+
- `execute_bulk_close()` - Close multiple cases with reasons
22+
- `execute_bulk_reopen()` - Reopen multiple cases
23+
- Complete CLI support for case management through `secops case` commands
24+
- `secops case get` - Get single case details
25+
- `secops case list` - List cases with filtering and pagination
26+
- `secops case update` - Update case properties
27+
- `secops case merge` - Merge multiple cases
28+
- `secops case bulk-*` commands for bulk operations
29+
830
## [0.36.0] - 2026-03-10
931
### Added
1032
- Raw log search functionality with `search_raw_logs()` method

CLI.md

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1041,6 +1041,8 @@ secops rule-exclusion compute-activity \
10411041

10421042
### Case Management
10431043

1044+
Chronicle also provides comprehensive case management capabilities for tracking and managing security investigations. The CLI supports listing, retrieving, updating, and performing bulk operations on cases.
1045+
10441046
Get case details for specific case IDs:
10451047

10461048
```bash
@@ -1058,7 +1060,74 @@ secops alert --time-window 24 --max-alerts 50 > alerts.json
10581060
secops case --ids "case-123,case-456"
10591061
```
10601062
1061-
> **Note**: The case management uses a batch API that can retrieve multiple cases in a single request. You can provide up to 1000 case IDs separated by commas.
1063+
> **Note**: You can provide up to 1000 case IDs separated by commas.
1064+
1065+
#### List cases
1066+
1067+
```bash
1068+
# List all cases with default pagination
1069+
secops case list --page-size 50
1070+
1071+
# List with filtering
1072+
secops case list --page-size 100 --filter 'status = "OPENED"' --order-by "createTime desc"
1073+
1074+
# Get cases as a flat list instead of paginated dict
1075+
secops case list --page-size 50 --as-list
1076+
```
1077+
1078+
#### Get case details
1079+
1080+
```bash
1081+
# Get a specific case by ID
1082+
secops case get --id "12345"
1083+
1084+
# Get case with expanded fields
1085+
secops case get --id "12345" --expand "tags,products"
1086+
1087+
# Legacy: Get multiple cases by IDs (batch API)
1088+
secops case --ids "case-123,case-456"
1089+
```
1090+
1091+
> **Note**: The legacy batch API can retrieve up to 1000 case IDs in a single request.
1092+
1093+
#### Update a case
1094+
1095+
```bash
1096+
# Update case priority
1097+
secops case update --id "12345" --data '{"priority": "PRIORITY_HIGH"}' --update-mask "priority"
1098+
1099+
# Update multiple fields
1100+
secops case update --id "12345" --data '{"priority": "PRIORITY_MEDIUM", "stage": "Investigation"}' --update-mask "priority,stage"
1101+
```
1102+
1103+
#### Merge cases
1104+
1105+
```bash
1106+
# Merge source cases into target case
1107+
secops case merge --source-ids "12345,67890" --target-id "11111"
1108+
```
1109+
1110+
#### Bulk operations
1111+
1112+
```bash
1113+
# Bulk add tags to cases
1114+
secops case bulk-add-tag --ids "12345,67890" --tags "phishing,high-priority"
1115+
1116+
# Bulk assign cases to a user
1117+
secops case bulk-assign --ids "12345,67890" --username "@SecurityTeam"
1118+
1119+
# Bulk change priority
1120+
secops case bulk-change-priority --ids "12345,67890" --priority "HIGH"
1121+
1122+
# Bulk change stage
1123+
secops case bulk-change-stage --ids "12345,67890" --stage "Remediation"
1124+
1125+
# Bulk close cases
1126+
secops case bulk-close --ids "12345,67890" --close-reason "NOT_MALICIOUS" --root-cause "False positive - benign activity"
1127+
1128+
# Bulk reopen cases
1129+
secops case bulk-reopen --ids "12345,67890" --reopen-comment "New evidence discovered"
1130+
```
10621131
10631132
### Investigation Management
10641133

README.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1424,6 +1424,134 @@ case = cases.get_case("case-id-1")
14241424

14251425
> **Note**: The case management API uses the `legacy:legacyBatchGetCases` endpoint to retrieve multiple cases in a single request. You can retrieve up to 1000 cases in a single batch.
14261426
1427+
### Case Management
1428+
1429+
Chronicle provides comprehensive case management capabilities for tracking and managing security investigations. The SDK supports listing, retrieving, updating, and performing bulk operations on cases.
1430+
1431+
#### List cases
1432+
1433+
Retrieve cases with optional filtering and pagination:
1434+
1435+
```python
1436+
# List all cases with default pagination
1437+
result = chronicle.list_cases(page_size=50)
1438+
for case_data in result["cases"]:
1439+
case_id = case_data["name"].split("/")[-1]
1440+
print(f"Case {case_id}: {case_data['displayName']}")
1441+
1442+
# List with filtering
1443+
open_cases = chronicle.list_cases(
1444+
page_size=100,
1445+
filter_query='status = "OPENED"',
1446+
order_by="createTime desc"
1447+
)
1448+
1449+
# Get cases as a flat list instead of paginated dict
1450+
cases_list = chronicle.list_cases(page_size=50, as_list=True)
1451+
for case in cases_list:
1452+
print(f"{case['displayName']}: {case['priority']}")
1453+
```
1454+
1455+
#### Get case details
1456+
1457+
Retrieve detailed information about a specific case:
1458+
1459+
```python
1460+
# Get case by ID
1461+
case = chronicle.get_case("12345")
1462+
print(f"Case: {case.display_name}")
1463+
print(f"Priority: {case.priority}")
1464+
print(f"Status: {case.status}")
1465+
print(f"Stage: {case.stage}")
1466+
1467+
# Get case with expanded fields
1468+
case_expanded = chronicle.get_case("12345", expand="tags,products")
1469+
```
1470+
1471+
#### Update a case
1472+
1473+
Update case fields using partial updates:
1474+
1475+
```python
1476+
# Update case priority
1477+
updated_case = chronicle.patch_case(
1478+
case_name="12345",
1479+
case_data={"priority": "PRIORITY_HIGH"},
1480+
update_mask="priority"
1481+
)
1482+
1483+
# Update multiple fields
1484+
updated_case = chronicle.patch_case(
1485+
case_name="12345",
1486+
case_data={
1487+
"priority": "PRIORITY_MEDIUM",
1488+
"stage": "Investigation"
1489+
},
1490+
update_mask="priority,stage"
1491+
)
1492+
```
1493+
1494+
#### Merge cases
1495+
1496+
Merge multiple cases into a single target case:
1497+
1498+
```python
1499+
# Merge source cases into target case
1500+
result = chronicle.merge_cases(
1501+
case_ids=[12345, 67890],
1502+
case_to_merge_with=11111
1503+
)
1504+
1505+
if result.get("isRequestValid"):
1506+
print(f"Cases merged into case {result['newCaseId']}")
1507+
else:
1508+
print(f"Merge failed: {result.get('errors')}")
1509+
```
1510+
1511+
#### Bulk operations
1512+
1513+
Perform operations on multiple cases simultaneously:
1514+
1515+
```python
1516+
# Bulk add tags
1517+
chronicle.execute_bulk_add_tag(
1518+
case_ids=[12345, 67890],
1519+
tags=["phishing", "high-priority"]
1520+
)
1521+
1522+
# Bulk assign cases
1523+
chronicle.execute_bulk_assign(
1524+
case_ids=[12345, 67890],
1525+
username="@SecurityTeam"
1526+
)
1527+
1528+
# Bulk change priority
1529+
chronicle.execute_bulk_change_priority(
1530+
case_ids=[12345, 67890],
1531+
priority="PRIORITY_HIGH"
1532+
)
1533+
1534+
# Bulk change stage
1535+
chronicle.execute_bulk_change_stage(
1536+
case_ids=[12345, 67890],
1537+
stage="Remediation"
1538+
)
1539+
1540+
# Bulk close cases
1541+
chronicle.execute_bulk_close(
1542+
case_ids=[12345, 67890],
1543+
close_reason="NOT_MALICIOUS",
1544+
root_cause="False positive - benign activity",
1545+
close_comment="Verified with asset owner"
1546+
)
1547+
1548+
# Bulk reopen cases
1549+
chronicle.execute_bulk_reopen(
1550+
case_ids=[12345, 67890],
1551+
reopen_comment="New evidence discovered"
1552+
)
1553+
```
1554+
14271555
### Investigation Management
14281556

14291557
Chronicle investigations provide automated analysis and recommendations for alerts and cases. The SDK provides methods to list, retrieve, trigger, and fetch associated investigations.

api_module_mapping.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Following shows mapping between SecOps [REST Resource](https://cloud.google.com/
77
## Implementation Statistics
88

99
- **v1:** 17 endpoints implemented
10+
- **v1beta:** 10 endpoints implemented
1011
- **v1alpha:** 113 endpoints implemented
1112

1213
## Endpoint Mapping
@@ -85,6 +86,16 @@ Following shows mapping between SecOps [REST Resource](https://cloud.google.com/
8586
| watchlists.get | v1beta | | |
8687
| watchlists.list | v1beta | | |
8788
| watchlists.patch | v1beta | | |
89+
| cases.executeBulkAddTag | v1beta | chronicle.case.execute_bulk_add_tag | secops case bulk-add-tag |
90+
| cases.executeBulkAssign | v1beta | chronicle.case.execute_bulk_assign | secops case bulk-assign |
91+
| cases.executeBulkChangePriority | v1beta | chronicle.case.execute_bulk_change_priority | secops case bulk-change-priority |
92+
| cases.executeBulkChangeStage | v1beta | chronicle.case.execute_bulk_change_stage | secops case bulk-change-stage |
93+
| cases.executeBulkClose | v1beta | chronicle.case.execute_bulk_close | secops case bulk-close |
94+
| cases.executeBulkReopen | v1beta | chronicle.case.execute_bulk_reopen | secops case bulk-reopen |
95+
| cases.get | v1beta | chronicle.case.get_case | secops case get |
96+
| cases.list | v1beta | chronicle.case.list_cases | secops case list |
97+
| cases.merge | v1beta | chronicle.case.merge_cases | secops case merge |
98+
| cases.patch | v1beta | chronicle.case.patch_case | secops case update |
8899
| analytics.entities.analyticValues.list | v1alpha | | |
89100
| analytics.list | v1alpha | | |
90101
| batchValidateWatchlistEntities | v1alpha | | |

0 commit comments

Comments
 (0)