Skip to content

Commit b43aea3

Browse files
committed
Add IoC API resources
1 parent cee0332 commit b43aea3

File tree

5 files changed

+395
-1
lines changed

5 files changed

+395
-1
lines changed

iocs/v1alpha/batch_get_iocs.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
#!/usr/bin/env python3
2+
3+
# Copyright 2025 Google LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
"""Get multiple IoCs from Chronicle."""
18+
19+
from typing import List
20+
21+
from common import regions
22+
from google.auth.transport import requests
23+
24+
CHRONICLE_API_BASE_URL = "https://chronicle.googleapis.com"
25+
26+
27+
def batch_get_iocs(
28+
http_session: requests.AuthorizedSession,
29+
proj_id: str,
30+
proj_instance: str,
31+
proj_region: str,
32+
ioc_values: List[str],
33+
ioc_type: str,
34+
) -> dict:
35+
"""Get multiple IoCs by their values from Chronicle.
36+
37+
Args:
38+
http_session: Authorized session for HTTP requests.
39+
proj_id: GCP project id or number to which the target instance belongs.
40+
proj_instance: Customer ID (uuid with dashes) for the instance.
41+
proj_region: region in which the target project is located.
42+
ioc_values: List of IoC values to retrieve.
43+
ioc_type: Type of IoCs being requested. One of:
44+
IOC_TYPE_UNSPECIFIED
45+
DOMAIN
46+
IP
47+
FILE_HASH
48+
URL
49+
USER_EMAIL
50+
MUTEX
51+
FILE_HASH_MD5
52+
FILE_HASH_SHA1
53+
FILE_HASH_SHA256
54+
IOC_TYPE_RESOURCE
55+
56+
Returns:
57+
Dict containing the requested IoCs.
58+
59+
Raises:
60+
requests.exceptions.HTTPError: HTTP request resulted in an error
61+
(response.status_code >= 400).
62+
"""
63+
base_url_with_region = regions.url_always_prepend_region(
64+
CHRONICLE_API_BASE_URL, proj_region)
65+
instance = f"projects/{proj_id}/locations/{proj_region}/instances/{proj_instance}"
66+
url = f"{base_url_with_region}/v1alpha/{instance}/iocs:batchGet"
67+
68+
body = {
69+
"ioc_values": ioc_values,
70+
"ioc_type": ioc_type,
71+
}
72+
73+
response = http_session.request(
74+
"POST",
75+
url,
76+
json=body,
77+
)
78+
if response.status_code >= 400:
79+
print(response.text)
80+
response.raise_for_status()
81+
return response.json()

iocs/v1alpha/get_ioc.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/usr/bin/env python3
2+
3+
# Copyright 2025 Google LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
"""Get a single IoC from Chronicle."""
18+
19+
from common import regions
20+
from google.auth.transport import requests
21+
22+
CHRONICLE_API_BASE_URL = "https://chronicle.googleapis.com"
23+
24+
25+
def get_ioc(
26+
http_session: requests.AuthorizedSession,
27+
proj_id: str,
28+
proj_instance: str,
29+
proj_region: str,
30+
ioc_value: str,
31+
ioc_type: str,
32+
) -> dict:
33+
"""Get a single IoC by its value from Chronicle.
34+
35+
Args:
36+
http_session: Authorized session for HTTP requests.
37+
proj_id: GCP project id or number to which the target instance belongs.
38+
proj_instance: Customer ID (uuid with dashes) for the instance.
39+
proj_region: region in which the target project is located.
40+
ioc_value: Value of the IoC to retrieve.
41+
ioc_type: Type of IoC being requested. One of:
42+
IOC_TYPE_UNSPECIFIED
43+
DOMAIN
44+
IP
45+
FILE_HASH
46+
URL
47+
USER_EMAIL
48+
MUTEX
49+
FILE_HASH_MD5
50+
FILE_HASH_SHA1
51+
FILE_HASH_SHA256
52+
IOC_TYPE_RESOURCE
53+
54+
Returns:
55+
Dict containing the requested IoC.
56+
57+
Raises:
58+
requests.exceptions.HTTPError: HTTP request resulted in an error
59+
(response.status_code >= 400).
60+
"""
61+
base_url_with_region = regions.url_always_prepend_region(
62+
CHRONICLE_API_BASE_URL, proj_region)
63+
instance = f"projects/{proj_id}/locations/{proj_region}/instances/{proj_instance}"
64+
url = f"{base_url_with_region}/v1alpha/{instance}/iocs/{ioc_type}/{ioc_value}"
65+
66+
response = http_session.request("GET", url)
67+
if response.status_code >= 400:
68+
print(response.text)
69+
response.raise_for_status()
70+
return response.json()

iocs/v1alpha/get_ioc_state.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/usr/bin/env python3
2+
3+
# Copyright 2025 Google LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
"""Get the state of an IoC from Chronicle."""
18+
19+
from common import regions
20+
from google.auth.transport import requests
21+
22+
CHRONICLE_API_BASE_URL = "https://chronicle.googleapis.com"
23+
24+
25+
def get_ioc_state(
26+
http_session: requests.AuthorizedSession,
27+
proj_id: str,
28+
proj_instance: str,
29+
proj_region: str,
30+
ioc_value: str,
31+
ioc_type: str,
32+
) -> dict:
33+
"""Get the state of an IoC by its value from Chronicle.
34+
35+
Args:
36+
http_session: Authorized session for HTTP requests.
37+
proj_id: GCP project id or number to which the target instance belongs.
38+
proj_instance: Customer ID (uuid with dashes) for the instance.
39+
proj_region: region in which the target project is located.
40+
ioc_value: Value of the IoC to get state for.
41+
ioc_type: Type of IoC being requested. One of:
42+
IOC_TYPE_UNSPECIFIED
43+
DOMAIN
44+
IP
45+
FILE_HASH
46+
URL
47+
USER_EMAIL
48+
MUTEX
49+
FILE_HASH_MD5
50+
FILE_HASH_SHA1
51+
FILE_HASH_SHA256
52+
IOC_TYPE_RESOURCE
53+
54+
Returns:
55+
Dict containing the IoC state.
56+
57+
Raises:
58+
requests.exceptions.HTTPError: HTTP request resulted in an error
59+
(response.status_code >= 400).
60+
"""
61+
base_url_with_region = regions.url_always_prepend_region(
62+
CHRONICLE_API_BASE_URL, proj_region)
63+
instance = f"projects/{proj_id}/locations/{proj_region}/instances/{proj_instance}"
64+
url = f"{base_url_with_region}/v1alpha/{instance}/iocs/{ioc_type}/{ioc_value}:getIocState"
65+
66+
response = http_session.request("GET", url)
67+
if response.status_code >= 400:
68+
print(response.text)
69+
response.raise_for_status()
70+
return response.json()

sdk/cli.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
from sdk.commands import detect
2525
from sdk.commands import ingestion
26+
from sdk.commands import iocs
2627
from sdk.commands import lists
2728
from sdk.commands import search
2829

@@ -56,14 +57,15 @@ def add_common_options(func):
5657
def cli():
5758
"""Chronicle API Command Line Interface.
5859
59-
This CLI provides access to Chronicle's detection, ingestion, search, and lists APIs.
60+
This CLI provides access to Chronicle's detection, ingestion, IoCs, search, and lists APIs.
6061
"""
6162
pass
6263

6364

6465
# Add command groups
6566
cli.add_command(detect.detect)
6667
cli.add_command(ingestion.ingestion)
68+
cli.add_command(iocs.iocs)
6769
cli.add_command(lists.lists)
6870
cli.add_command(search.search)
6971

0 commit comments

Comments
 (0)