Skip to content
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
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
how a consumer would use the library or CLI tool (e.g. adding unit tests, updating documentation, etc) are not captured
here.

## Unreleased
## 2.12.0 - 2026-05-04

### Added
- Added the `sdk.file-events.v2.search_groups` method to get approximate aggregate file event counts by a given grouping term.
Expand All @@ -19,6 +19,8 @@
- Added the `is_high_value` option to trusted activity methods in the SDK, and the `--high-value` option to trusted activity methods in the CLI.
- Added the ability to specify domain trust for browser destinations, allowing users to specify when users should be allowed to use certain destinations when logged-in using a trusted domain.
- Added the ability to specify trust for file-transfer tools when adding a trusted domain.
- Added the `risk-indicator-categories` client to the SDK, allowing the listing of risk indicator categories, subcategories, and risk indicators.
- Added the `risk-indicator-categories` command to the CLI, allowing the listing of risk indicator categories.

## 2.11.0 - 2026-02-10

Expand Down
6 changes: 6 additions & 0 deletions docs/cli/cmds/risk-indicator-categories.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Risk Indicator Categories Commands

::: mkdocs-click
:module: _incydr_cli.cmds.risk_indicator_categories
:command: risk_indicator_categories
:list_subcommands:
2 changes: 1 addition & 1 deletion docs/sdk/client.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@

::: incydr.Client
:docstring:
:members: settings session request_history actors agents alerts alert_rules audit_log cases customer departments devices directory_groups file_events sessions trusted_activities users risk_profiles watchlists
:members: settings session request_history actors agents alerts alert_rules audit_log cases customer departments devices directory_groups file_events sessions trusted_activities users risk_profiles watchlists risk_indicator_categories
5 changes: 5 additions & 0 deletions docs/sdk/clients/risk_indicator_categories.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Risk Indicator Categories

::: _incydr_sdk.risk_indicator_categories.client.RiskIndicatorCategoriesV1
:docstring:
:members:
23 changes: 23 additions & 0 deletions docs/sdk/models.md
Original file line number Diff line number Diff line change
Expand Up @@ -329,3 +329,26 @@ ExcludedUsersList is deprecated. Use ExcludedActorsList instead.

::: incydr.models.IncludedDirectoryGroup
:docstring:

## Risk Indicator Categories
---

### `RiskIndicator` model

::: incydr.models.RiskIndicator
:docstring:

### `RiskIndicatorSubcategory` model

::: incydr.models.RiskIndicatorSubcategory
:docstring:

### `RiskIndicatorCategory` model

::: incydr.models.RiskIndicatorCategory
:docstring:

### `RiskIndicatorCategoriesResponsePage` model

::: incydr.models.RiskIndicatorCategoriesResponsePage
:docstring:
2 changes: 2 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ nav:
- File Event Querying: 'sdk/clients/file_event_queries.md'
- Legal Hold: 'sdk/clients/legal_hold.md'
- Orgs: 'sdk/clients/orgs.md'
- Risk Indicator Categories: 'sdk/clients/risk_indicator_categories.md'
- Sessions: 'sdk/clients/sessions.md'
- Trusted Activites: 'sdk/clients/trusted_activities.md'
- Users: 'sdk/clients/users.md'
Expand Down Expand Up @@ -84,6 +85,7 @@ nav:
- Files: 'cli/cmds/files.md'
- Legal Hold: 'cli/cmds/legal_hold.md'
- Orgs: 'cli/cmds/orgs.md'
- Risk Indicator Categories: 'cli/cmds/risk_indicator_categories.md'
- Sessions: 'cli/cmds/sessions.md'
- Trusted Activites: 'cli/cmds/trusted_activities.md'
- Users: 'cli/cmds/users.md'
Expand Down
103 changes: 103 additions & 0 deletions src/_incydr_cli/cmds/risk_indicator_categories.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import itertools
from typing import Iterator
from typing import Optional

import click

from _incydr_cli import console
from _incydr_cli import logging_options
from _incydr_cli import render
from _incydr_cli.cmds.options.output_options import columns_option
from _incydr_cli.cmds.options.output_options import table_format_option
from _incydr_cli.cmds.options.output_options import TableFormat
from _incydr_cli.core import IncydrCommand
from _incydr_cli.core import IncydrGroup
from _incydr_sdk.core.client import Client
from _incydr_sdk.risk_indicator_categories.models import RiskIndicator


@click.group(cls=IncydrGroup)
@logging_options
def risk_indicator_categories():
"""View and manage risk indicators."""


@risk_indicator_categories.command("list", cls=IncydrCommand)
@table_format_option
@columns_option
@logging_options
def list_categories(
format_: Optional[TableFormat] = None,
columns: Optional[str] = None,
):
"""
List Risk Indicators by category and subcategory.
"""
client = Client()
categories = client.risk_indicator_categories.v1.list_categories().categories

if format_ == TableFormat.table:
columns = columns or [
"id",
"name",
"description",
"category_name",
"category_id",
"subcategory_name",
"subcategory_id",
"type",
]
render.table(
RiskIndicatorTableEntry,
iter_risk_indicator_table_entries(categories),
columns=columns,
flat=False,
)
elif format_ == TableFormat.csv:
render.csv(
RiskIndicatorTableEntry,
iter_risk_indicator_table_entries(categories),
columns=columns,
flat=True,
)
else:
printed = False
for indicator in iter_risk_indicator_table_entries(categories):
printed = True
if format_ == TableFormat.json_pretty:
console.print_json(indicator.json())
else:
click.echo(indicator.json())
if not printed:
console.print("No results found.")


class RiskIndicatorTableEntry(RiskIndicator):
category_name: str
category_id: str
category_description: Optional[str]
subcategory_name: str
subcategory_id: str
subcategory_description: Optional[str]
type: str


def iter_risk_indicator_table_entries(categories) -> Iterator[RiskIndicatorTableEntry]:
for category in categories:
for subcategory in category.subcategories:
for indicator, indicator_type in itertools.chain(
((i, "standard") for i in subcategory.standard_indicators),
((i, "custom") for i in subcategory.custom_indicators),
):
yield RiskIndicatorTableEntry(
id=indicator.id,
name=indicator.name,
description=indicator.description,
category_name=category.name,
category_id=category.id,
category_description=category.description,
subcategory_name=subcategory.name,
subcategory_id=subcategory.id,
subcategory_description=subcategory.description,
type=indicator_type,
)
2 changes: 2 additions & 0 deletions src/_incydr_cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from _incydr_cli.cmds.files import files as files_client
from _incydr_cli.cmds.legal_hold import legal_hold
from _incydr_cli.cmds.orgs import orgs
from _incydr_cli.cmds.risk_indicator_categories import risk_indicator_categories
from _incydr_cli.cmds.risk_profiles import risk_profiles
from _incydr_cli.cmds.sessions import sessions
from _incydr_cli.cmds.trusted_activities import trusted_activities
Expand Down Expand Up @@ -87,6 +88,7 @@ def incydr(version, python, script_dir):
incydr.add_command(files_client)
incydr.add_command(cases)
incydr.add_command(risk_profiles)
incydr.add_command(risk_indicator_categories)
incydr.add_command(sessions)
incydr.add_command(trusted_activities)
incydr.add_command(users)
Expand Down
2 changes: 1 addition & 1 deletion src/_incydr_sdk/__version__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2022-present Code42 Software <integrations@code42.com>
#
# SPDX-License-Identifier: MIT
__version__ = "2.11.0"
__version__ = "2.12.0"
13 changes: 13 additions & 0 deletions src/_incydr_sdk/core/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from _incydr_sdk.files.client import FilesClient
from _incydr_sdk.legal_hold.client import LegalHoldClient
from _incydr_sdk.orgs.client import OrgsClient
from _incydr_sdk.risk_indicator_categories.client import RiskIndicatorCategories
from _incydr_sdk.risk_profiles.client import RiskProfiles
from _incydr_sdk.sessions.client import SessionsClient
from _incydr_sdk.trusted_activities.client import TrustedActivitiesClient
Expand Down Expand Up @@ -114,6 +115,7 @@ def response_hook(response, *args, **kwargs):
self._trusted_activities = TrustedActivitiesClient(self)
self._users = UsersClient(self)
self._risk_profiles = RiskProfiles(self)
self._risk_indicator_categories = RiskIndicatorCategories(self)
self._watchlists = WatchlistsClient(self)

if not skip_auth:
Expand Down Expand Up @@ -366,6 +368,17 @@ def risk_profiles(self):
"""
return self._risk_profiles

@property
def risk_indicator_categories(self):
"""
Property returning a [`RiskIndicatorCategories`](../risk_indicator_categories) client for interacting
with `/v*/risk_indicator_categories` API endpoints.

Usage:
>>> client.risk_indicator_categories.v1.list_categories(active=True)
"""
return self._risk_indicator_categories

@property
def watchlists(self):
"""
Expand Down
84 changes: 84 additions & 0 deletions src/_incydr_sdk/risk_indicator_categories/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from _incydr_sdk.enums import SortDirection
from _incydr_sdk.risk_indicator_categories.models import (
RiskIndicatorCategoriesResponsePage,
)
from _incydr_sdk.risk_indicator_categories.models import RiskIndicatorCategory
from _incydr_sdk.risk_indicator_categories.models import RiskIndicatorSubcategory


class RiskIndicatorCategories:
def __init__(self, parent):
self._parent = parent
self._v1 = None

@property
def v1(self):
if self._v1 is None:
self._v1 = RiskIndicatorCategoriesV1(self._parent)
return self._v1


class RiskIndicatorCategoriesV1:
"""
Client for `/v1/risk-indicator-categories` endpoints.

Usage example:

>>> import incydr
>>> client = incydr.Client(**kwargs)
>>> client.risk_indicators.v1.list_categories()
"""

def __init__(self, parent):
self._parent = parent

def list_categories(
self, active: bool = None, sort_direction: SortDirection = None
) -> RiskIndicatorCategoriesResponsePage:
"""
Returns all risk indicator categories, including their subcategories and associated risk indicators.
Filter results by passing the appropriate parameters:

**Parameters**:

* **active**: `bool` - When provided, returns only those risk indicators which match the provided value (true or false). When not provided, returns both.
* **sort_direction**: `SortDirection` - The order in which to sort the returned list.

**Returns**: A [`RiskIndicatorCategoriesResponsePage`][riskindicatorcategoriesresponsepage-model] object.
"""
response = self._parent.session.get(
"/v1/risk-indicator-categories",
params={"isActive": active, "sort_direction": sort_direction},
)
return RiskIndicatorCategoriesResponsePage.parse_response(response)

def get_category(self, id: str) -> RiskIndicatorCategory:
"""
Returns a single risk indicator category, including its subcategories and associated risk indicators.

**Parameters**:

* **id**: `str` - The unique ID of the category you wish to retrieve.

**Returns**: A [`RiskIndicatorCategory`][riskindicatorcategory-model] object.
"""
response = self._parent.session.get(f"/v1/risk-indicator-categories/{id}")
return RiskIndicatorCategory.parse_response(response)

def get_subcategory(
self, category_id: str, subcategory_id: str
) -> RiskIndicatorSubcategory:
"""
Returns a single risk indicator category, including its subcategories and associated risk indicators.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should this say something like:

Suggested change
Returns a single risk indicator category, including its subcategories and associated risk indicators.
Returns a single risk indicator subcategory, including its associated risk indicators.


**Parameters**:

* **category_id**: `str` - The unique ID of the category in which the subcategory lives.
* **subcategory_id**: `str` - The unique ID of the subcategory you wish to retrieve.

**Returns**: A [`RiskIndicatorSubcategory`][riskindicatorsubcategory-model] object.
"""
response = self._parent.session.get(
f"/v1/risk-indicator-categories/{category_id}/subcategories/{subcategory_id}"
)
return RiskIndicatorSubcategory.parse_response(response)
Loading
Loading