DFIRe
Integration with DFIRe (Digital Forensics and Incident Response) platform for case management and IOC indicator tracking.
Forensics & Malware Analysis · DFIRe
Details
| ID | DFIRe |
|---|---|
| Provider | DFIRe |
| Category | Forensics & Malware Analysis |
| From Version | 6.10.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
README
DFIRe
DFIRe is a self-hosted Digital Forensics and Incident Response (DFIR) case management platform built for security professionals. It provides structured case management, evidence tracking with chain of custody, IOC indicator management, and incident response workflows aligned with the NIST Incident Response framework — all running on your own infrastructure with AES-256 encryption.
This integration connects Cortex XSIAM and Cortex XSOAR to a DFIRe instance, enabling automated case creation and updates, bi-directional IOC indicator synchronization, evidence item tracking, file attachment uploads, and timeline enrichment directly from playbooks.
Configure DFIRe in Cortex
| Parameter | Description | Required |
|---|---|---|
| Server URL | URL of your DFIRe instance (e.g. https://dfire.example.com). |
True |
| API Key | Bearer API key (dfire_ak_...). Create under Settings > API Keys in DFIRe. |
True |
| Trust any certificate (not secure) | Skip TLS verification for self-signed certs. | False |
| Use system proxy settings | Route requests through the configured proxy. | False |
Commands
You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.
dfire-search
Searches across all DFIRe data (cases, indicators, notes, items). Supports AND, OR, NOT operators.
Base Command
dfire-search
Input
| Argument Name | Description | Required |
|---|---|---|
| query | The search query (min 2 characters). | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.Search.id | String | The result ID. |
| DFIRe.Search.type | String | The result type (e.g. case, indicator, note). |
| DFIRe.Search.title | String | The result title. |
| DFIRe.Search.snippet | String | The matching text snippet. |
| DFIRe.Search.rank | Number | The search relevance rank. |
| DFIRe.Search.url | String | The URL to the result in DFIRe. |
| DFIRe.Search.date | Date | The result date. |
dfire-case-type-list
Lists available case types and their IDs.
Base Command
dfire-case-type-list
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.CaseType.id | Number | The case type ID. |
| DFIRe.CaseType.name | String | The case type name. |
dfire-case-list
Lists cases from DFIRe.
Base Command
dfire-case-list
Input
| Argument Name | Description | Required |
|---|---|---|
| limit | The maximum number of cases to return. Default is 50. | Optional |
| page | The page number for pagination. | Optional |
| status | The status by which to filter cases. Possible values are: OPEN, CLOSED, ARCHIVED. | Optional |
| status_in | A comma-separated list of statuses by which to filter cases, for example, “OPEN,CLOSED”. | Optional |
| severity | The severity by which to filter cases. Possible values are: critical, high, medium, low, info. | Optional |
| case_mode | The mode by which to filter cases. Possible values are: investigation, incident. | Optional |
| lead_investigator | The lead investigator user ID by which to filter cases. | Optional |
| created_at_gte | The ISO-8601 datetime on or after which to filter cases, for example, “2026-05-01T00:00:00Z”. | Optional |
| created_at_lte | The ISO-8601 datetime on or before which to filter cases. | Optional |
| ordering | The field by which to order results, for example, “created_at”, or “-created_at” for descending order. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.Case.id | Number | The case ID. |
| DFIRe.Case.title | String | The case title. |
| DFIRe.Case.case_number | String | The case number. |
| DFIRe.Case.status | String | The case status. |
| DFIRe.Case.severity | String | The case severity. |
| DFIRe.Case.case_mode | String | The case mode, investigation or incident. |
| DFIRe.Case.case_type_name | String | The case type name. |
| DFIRe.Case.lead_investigator | Number | The lead investigator user ID. |
| DFIRe.Case.created_at | Date | Case creation timestamp. |
dfire-case-get
Retrieves details of a specific case.
Base Command
dfire-case-get
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the case. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.Case.id | Number | The case ID. |
| DFIRe.Case.title | String | The case title. |
| DFIRe.Case.case_number | String | The case number. |
| DFIRe.Case.description | String | The case description. |
| DFIRe.Case.notes | String | The high-level case notes. |
| DFIRe.Case.status | String | The case status. |
| DFIRe.Case.severity | String | The case severity. |
| DFIRe.Case.case_mode | String | The case mode, investigation or incident. |
| DFIRe.Case.case_type | Number | The case type ID. |
| DFIRe.Case.case_type_name | String | The case type name. |
| DFIRe.Case.external_id | String | The external reference ID. |
| DFIRe.Case.lead_investigator | Number | The lead investigator user ID. |
| DFIRe.Case.project_id | Number | The associated project ID. |
| DFIRe.Case.current_phase_name | String | The current case phase name. |
| DFIRe.Case.item_count | Number | The number of evidence items. |
| DFIRe.Case.indicator_count | Number | The number of indicators. |
| DFIRe.Case.created_at | Date | The case creation timestamp. |
| DFIRe.Case.closed_at | Date | The case closure timestamp. |
dfire-case-create
Creates a new case in DFIRe.
Base Command
dfire-case-create
Input
| Argument Name | Description | Required |
|---|---|---|
| title | The case title. | Required |
| case_type | The case type ID. | Required |
| description | The case description. | Optional |
| notes | The high-level case summary or notes. | Optional |
| severity | The case severity. Possible values are: critical, high, medium, low, info. | Optional |
| case_mode | The case mode, investigation or incident. Possible values are: investigation, incident. | Optional |
| lead_investigator | The user ID of the lead investigator. | Optional |
| investigators | A comma-separated list of investigator user IDs. | Optional |
| viewers | A comma-separated list of viewer user IDs. | Optional |
| investigator_ids | A comma-separated list of investigator IDs (alternate write field). | Optional |
| viewer_ids | A comma-separated list of viewer IDs (alternate write field). | Optional |
| incident_category | The ENISA incident category ID. | Optional |
| outcome_verdict | The outcome verdict ID (true positive, false positive, etc.). | Optional |
| external_id | The external reference ID (e.g. ticket number). | Optional |
| project_id | The project ID to associate the case with. | Optional |
| attributes | The JSON string of custom attributes to attach to the case. | Optional |
| create_slack_channel | Whether to auto-create a Slack channel for this case. Defaults to false to avoid unintended channel creation from automated workflows. Possible values are: true, false. Default is false. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.Case.id | Number | The ID of the created case. |
| DFIRe.Case.title | String | The title of the created case. |
| DFIRe.Case.case_number | String | The assigned case number. |
| DFIRe.Case.status | String | The case status. |
dfire-case-update
Updates an existing case in DFIRe.
Base Command
dfire-case-update
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the case to update. | Required |
| title | The new title for the case. | Optional |
| description | The new case description. | Optional |
| notes | The high-level case summary or notes. | Optional |
| status | The new case status. Possible values are: OPEN, CLOSED, ARCHIVED. | Optional |
| severity | The new case severity. Possible values are: critical, high, medium, low, info. | Optional |
| case_mode | The new case mode, investigation or incident. Possible values are: investigation, incident. | Optional |
| lead_investigator | The new case lead investigator user ID. | Optional |
| investigators | A comma-separated list of user IDs with which to replace the investigator list.. | Optional |
| viewers | A comma-separated list of user IDs with which to replace the viewer list. | Optional |
| investigator_ids | A comma-separated list of investigator IDs (alternate write field). | Optional |
| viewer_ids | A comma-separated list of viewer IDs (alternate write field). | Optional |
| incident_category | The ENISA incident category ID. | Optional |
| outcome_verdict | The outcome verdict ID. | Optional |
| external_id | The new external reference ID. | Optional |
| attributes | The JSON string of custom attributes to attach to the case. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.Case.id | Number | The case ID. |
| DFIRe.Case.title | String | The updated case title. |
| DFIRe.Case.status | String | The updated case status. |
dfire-case-delete
Deletes a case from DFIRe.
Base Command
dfire-case-delete
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The ID of the case to delete. | Required |
Context Output
There is no context output for this command.
dfire-case-note-list
Lists notes for a case.
Base Command
dfire-case-note-list
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The case ID to list notes for. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.CaseNote.id | Number | The note ID. |
| DFIRe.CaseNote.case | Number | The case ID. |
| DFIRe.CaseNote.note | String | The note content. |
| DFIRe.CaseNote.author_name | String | The note author. |
| DFIRe.CaseNote.created_at | Date | The note creation timestamp. |
dfire-case-note-create
Creates a note on a case.
Base Command
dfire-case-note-create
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The case ID to add the note to. | Required |
| note | The note content. | Required |
| show_on_timeline | Whether to show this note on the case timeline. Possible values are: true, false. Default is false. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.CaseNote.id | Number | The created note ID. |
| DFIRe.CaseNote.case | Number | The case ID. |
| DFIRe.CaseNote.note | String | The note content. |
dfire-indicator-list
Lists indicators from the global IOC registry.
Base Command
dfire-indicator-list
Input
| Argument Name | Description | Required |
|---|---|---|
| limit | The maximum number of indicators to return. Default is 50. | Optional |
| offset | The offset for pagination. Default is 0. | Optional |
| search | The search term by which to filter indicators. | Optional |
| stix_type | The STIX type by which to filter indicators. Possible values are: ipv4-addr, ipv6-addr, domain-name, url, email-addr, email-message, file, process, windows-registry-key, network-traffic, user-account, mac-addr, software, artifact, autonomous-system, directory, mutex, x509-certificate. | Optional |
| classification | The classification by which to filter indicators. Possible values are: unknown, benign, suspicious, malicious. | Optional |
| confidence | The confidence level by which to filter indicators. Possible values are: low, medium, high. | Optional |
| tlp | The TLP designation by which to filter indicators. Possible values are: clear, green, amber, amber_strict, red. | Optional |
| is_published | Whether to filter indicators by published status. Possible values are: true, false. | Optional |
| is_revoked | Whether to filter indicators by revoked status. Possible values are: true, false. | Optional |
| parent | The ID of the parent indicator by which to filter results to return its child indicators. | Optional |
| ordering | The field by which to order results, for example, “created_at”, or “-confidence” for descending order. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.Indicator.id | Number | The indicator ID. |
| DFIRe.Indicator.value | String | The IOC value. |
| DFIRe.Indicator.stix_type | String | The STIX 2.1 SCO type. |
| DFIRe.Indicator.classification | String | The indicator classification (unknown/benign/suspicious/malicious). |
| DFIRe.Indicator.confidence | String | The indicator confidence level. |
| DFIRe.Indicator.tlp | String | The indicator TLP designation. |
| DFIRe.Indicator.is_published | Boolean | Whether the indicator is published. |
| DFIRe.Indicator.is_revoked | Boolean | Whether the indicator is revoked. |
| DFIRe.Indicator.case_count | Number | The number of associated cases for the indicator. |
| DFIRe.Indicator.first_seen | Date | The indicator first seen timestamp. |
| DFIRe.Indicator.created_at | Date | The indicator creation timestamp. |
dfire-indicator-get
Retrieves details of a specific indicator.
Base Command
dfire-indicator-get
Input
| Argument Name | Description | Required |
|---|---|---|
| indicator_id | The indicator ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.Indicator.id | Number | The DFIRe indicator ID. |
| DFIRe.Indicator.value | String | The IOC value. |
| DFIRe.Indicator.value_normalized | String | The normalized IOC value. |
| DFIRe.Indicator.stix_type | String | The STIX 2.1 SCO type. |
| DFIRe.Indicator.classification | String | The indicator classification. |
| DFIRe.Indicator.confidence | String | The indicator confidence level. |
| DFIRe.Indicator.tlp | String | The indicator TLP designation. |
| DFIRe.Indicator.tags | Unknown | The tags assigned to the indicator. |
| DFIRe.Indicator.public_notes | String | The indicator public notes. |
| DFIRe.Indicator.is_published | Boolean | Whether the indicator is published. |
| DFIRe.Indicator.is_revoked | Boolean | Whether the indicator is revoked. |
| DFIRe.Indicator.parent | Number | The parent indicator ID. |
| DFIRe.Indicator.case_count | Number | The number of associated cases for the indicator. |
| DFIRe.Indicator.children_count | Number | The number of child indicators. |
| DFIRe.Indicator.first_seen | Date | The indicator first seen timestamp. |
| DFIRe.Indicator.last_seen | Date | The indicator last seen timestamp. |
| DFIRe.Indicator.created_at | Date | The indicator creation timestamp. |
dfire-indicator-create
Creates a new indicator in the global IOC registry.
Base Command
dfire-indicator-create
Input
| Argument Name | Description | Required |
|---|---|---|
| value | The IOC value (IP, domain, hash, URL, etc.). | Required |
| stix_type | The STIX 2.1 SCO type. Possible values are: ipv4-addr, ipv6-addr, domain-name, url, email-addr, email-message, file, process, windows-registry-key, network-traffic, user-account, mac-addr, software, artifact, autonomous-system, directory, mutex, x509-certificate. | Required |
| classification | The indicator classification. Possible values are: unknown, benign, suspicious, malicious. | Optional |
| confidence | The indicator confidence level. Possible values are: low, medium, high. | Optional |
| tlp | The incidator TLP designation. Possible values are: clear, green, amber, amber_strict, red. | Optional |
| tags | A comma-separated list of indicator tags. | Optional |
| public_notes | The public notes about the indicator. | Optional |
| valid_until | The indicator auto-revoke date (ISO 8601). | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.Indicator.id | Number | The created indicator ID. |
| DFIRe.Indicator.value | String | The indicator value. |
| DFIRe.Indicator.stix_type | String | The indicator STIX type. |
| DFIRe.Indicator.is_existing | Boolean | Whether the indicator already exists. |
dfire-indicator-update
Updates an existing indicator.
Base Command
dfire-indicator-update
Input
| Argument Name | Description | Required |
|---|---|---|
| indicator_id | The indicator ID to update. | Required |
| classification | The new indicator classification. Possible values are: unknown, benign, suspicious, malicious. | Optional |
| confidence | The new indicator confidence level. Possible values are: low, medium, high. | Optional |
| tlp | The new indicator TLP designation. Possible values are: clear, green, amber, amber_strict, red. | Optional |
| tags | A comma-separated list of new indicator tags (replaces the existing). | Optional |
| public_notes | The new indicator public notes. | Optional |
| valid_until | The new indicator auto-revoke date (ISO 8601). Set it to empty to clear. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.Indicator.id | Number | The indicator ID. |
| DFIRe.Indicator.value | String | The IOC value. |
| DFIRe.Indicator.classification | String | The updated indicator classification. |
dfire-indicator-delete
Deletes an indicator from the global IOC registry.
Base Command
dfire-indicator-delete
Input
| Argument Name | Description | Required |
|---|---|---|
| indicator_id | The indicator ID to delete. | Required |
Context Output
There is no context output for this command.
dfire-item-type-list
Lists available evidence item types and their IDs.
Base Command
dfire-item-type-list
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.ItemType.id | Number | The item type ID. |
| DFIRe.ItemType.name | String | The item type name. |
| DFIRe.ItemType.icon | String | The item type icon. |
dfire-item-flag-list
Lists available item flags and their IDs.
Base Command
dfire-item-flag-list
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.ItemFlag.id | Number | The flag ID. |
| DFIRe.ItemFlag.name | String | The flag name. |
| DFIRe.ItemFlag.color | String | The flag color. |
| DFIRe.ItemFlag.description | String | The flag description. |
dfire-item-list
Lists evidence items, optionally filtered by case.
Base Command
dfire-item-list
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The case ID by which to filter evidence items. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.Item.uuid | String | The evidence item UUID. |
| DFIRe.Item.name | String | The evidence item name. |
| DFIRe.Item.display_title | String | The evidence item display title. |
| DFIRe.Item.item_type_name | String | The evidence item type name. |
| DFIRe.Item.case | Number | The evidence item associated case ID. |
| DFIRe.Item.location | String | The evidence item location. |
| DFIRe.Item.attachment_count | Number | The number of attachments to the evidence item. |
| DFIRe.Item.created_at | Date | The evidence item creation timestamp. |
dfire-item-get
Retrieves details of a specific evidence item.
Base Command
dfire-item-get
Input
| Argument Name | Description | Required |
|---|---|---|
| item_id | The evidence item ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.Item.uuid | String | The evidence item UUID. |
| DFIRe.Item.name | String | The evidence item name. |
| DFIRe.Item.display_title | String | The evidence item display title. |
| DFIRe.Item.item_type_name | String | The evidence item type name. |
| DFIRe.Item.case | Number | The evidence item associated case ID. |
| DFIRe.Item.location | String | The evidence item location. |
| DFIRe.Item.attachment_count | Number | The number of attachments for the evidence item. |
| DFIRe.Item.created_at | Date | The evidence item creation timestamp. |
dfire-item-create
Creates a new evidence item on a case.
Base Command
dfire-item-create
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The case ID to add the evidence item to. | Required |
| item_type | The evidence item type ID. | Required |
| location | The evidence item location (e.g. storage location, lab). | Required |
| name | The friendly name/label for the evidence item. | Optional |
| owner_id | The legal entity ID of the evidence item owner. | Optional |
| primary_user_id | The legal entity ID of the primary user. | Optional |
| collected_by | The user ID of the collector. | Optional |
| parent_item | The UUID of the parent evidence item. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.Item.uuid | String | The created evidence item UUID. |
| DFIRe.Item.name | String | The evidence item name. |
| DFIRe.Item.case | Number | The case ID. |
dfire-attachment-list
Lists attachments, optionally filtered by evidence item UUID.
Base Command
dfire-attachment-list
Input
| Argument Name | Description | Required |
|---|---|---|
| item_uuid | The evidence item UUID by which to filter attachments. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.Attachment.id | Number | The attachment ID. |
| DFIRe.Attachment.filename | String | The attachment filename. |
| DFIRe.Attachment.mime_type | String | The attachment MIME type. |
| DFIRe.Attachment.size | Number | The attachment file size in bytes. |
| DFIRe.Attachment.category | String | The attachment category. |
| DFIRe.Attachment.case | Number | The attachment associated case ID. |
| DFIRe.Attachment.item | String | The attachment associated evidence item UUID. |
| DFIRe.Attachment.hash_sha256 | String | The SHA-256 hash of the plaintext file attachment. |
| DFIRe.Attachment.uploaded_by_name | String | Who uploaded the file attachment. |
| DFIRe.Attachment.uploaded_at | Date | The attachment upload timestamp. |
dfire-attachment-get
Gets details of a specific attachment.
Base Command
dfire-attachment-get
Input
| Argument Name | Description | Required |
|---|---|---|
| attachment_id | The attachment ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.Attachment.id | Number | The DFIRe attachment ID. |
| DFIRe.Attachment.filename | String | The attachment filename. |
| DFIRe.Attachment.mime_type | String | The attachment MIME type. |
| DFIRe.Attachment.size | Number | The attachment file size in bytes. |
| DFIRe.Attachment.category | String | The attachment category. |
| DFIRe.Attachment.description | String | The attachment user-provided description. |
| DFIRe.Attachment.hash_sha256 | String | The SHA-256 hash of the plaintext file attachment. |
| DFIRe.Attachment.status | String | The attachment upload/encryption status. |
| DFIRe.Attachment.storage_location | String | The attachment storage location (local, s3, smb). |
| DFIRe.Attachment.uploaded_at | Date | The attachment upload timestamp. |
dfire-attachment-upload
Uploads a file as an attachment to a case or evidence item.
Base Command
dfire-attachment-upload
Input
| Argument Name | Description | Required |
|---|---|---|
| entry_id | The War Room entry ID of the file to upload. | Required |
| case_id | The case ID to associate the attachment with. | Optional |
| item_uuid | The evidence item UUID to associate the attachment with. | Optional |
| filename | The name with which to override the filename. (default is the uploaded file name). | Optional |
| category | The attachment category. general routes to the encrypted file store and is relevant for most playbooks. evidence is reserved for evidence photos and routes to the image gallery, not the file store. Possible values are: general, evidence. Default is general. |
Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.Attachment.id | Number | The created attachment ID. |
| DFIRe.Attachment.filename | String | The attachment filename. |
| DFIRe.Attachment.size | Number | The attachment file size in bytes. |
dfire-attachment-delete
Deletes an attachment.
Base Command
dfire-attachment-delete
Input
| Argument Name | Description | Required |
|---|---|---|
| attachment_id | The attachment ID to delete. | Required |
Context Output
There is no context output for this command.
dfire-timeline-list
Lists timeline events for a case (newest first).
Base Command
dfire-timeline-list
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The case ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.TimelineEvent.id | Number | The timeline event ID. |
| DFIRe.TimelineEvent.event_type | String | The timeline event type. |
| DFIRe.TimelineEvent.subject | String | The timeline event subject. |
| DFIRe.TimelineEvent.details | String | The timeline event details. |
| DFIRe.TimelineEvent.event_datetime | Date | When the timeline event occurred. |
| DFIRe.TimelineEvent.created_by_name | String | Who created the timeline event. |
dfire-timeline-create
Adds a manual timeline event to a case.
Base Command
dfire-timeline-create
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The case ID. | Required |
| subject | The timeline event subject line. | Required |
| details | The timeline event description. | Optional |
| event_datetime | When the timeline event occurred (ISO 8601). Default is now. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.TimelineEvent.id | Number | The created timeline event ID. |
| DFIRe.TimelineEvent.subject | String | The timeline event subject. |
| DFIRe.TimelineEvent.event_datetime | Date | The timeline event timestamp. |
dfire-user-list
Lists users in the DFIRe tenant. Useful for looking up user IDs for assignments.
Base Command
dfire-user-list
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.User.id | Number | The DFIRe user ID. |
| DFIRe.User.username | String | The DFIRe username. |
| DFIRe.User.full_name | String | The DFIRe user’s full name. |
| DFIRe.User.email | String | The DFIRe user’s email. |
| DFIRe.User.is_active | Boolean | Whether the DFIRe user is active. |
| DFIRe.User.groups | Unknown | Groups the DFIRe user belongs to. |
dfire-case-indicator-list
Lists indicators associated with a case.
Base Command
dfire-case-indicator-list
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The case ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.CaseIndicator.id | Number | The association ID. |
| DFIRe.CaseIndicator.case | Number | The case ID. |
| DFIRe.CaseIndicator.indicator.id | Number | The indicator ID. |
| DFIRe.CaseIndicator.indicator.value | String | The indicator value. |
| DFIRe.CaseIndicator.indicator.stix_type | String | The indicator STIX type. |
| DFIRe.CaseIndicator.context | String | The case private notes about the associated indicator. |
| DFIRe.CaseIndicator.source | String | How the associated indicator was added. |
| DFIRe.CaseIndicator.created_at | Date | The association timestamp. |
| DFIRe.CaseIndicator.case_count | Number | The number of cases this indicator appears in. |
dfire-case-indicator-add
Adds an indicator to a case. Creates the indicator if it does not exist.
Base Command
dfire-case-indicator-add
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The case ID. | Required |
| value | The indicator value. | Required |
| stix_type | The indicator STIX 2.1 SCO type. Possible values are: ipv4-addr, ipv6-addr, domain-name, url, email-addr, email-message, file, process, windows-registry-key, network-traffic, user-account, mac-addr, software, artifact, autonomous-system, directory, mutex, x509-certificate. | Required |
| classification | The indicator classification. Possible values are: unknown, benign, suspicious, malicious. Default is unknown. | Optional |
| confidence | The indicator confidence level. Possible values are: low, medium, high. Default is low. | Optional |
| tlp | The indicator TLP designation. Possible values are: clear, green, amber, amber_strict, red. Default is amber. | Optional |
| context | The case private notes about the indicator. | Optional |
| tags | A comma-separated list of indicator tags. | Optional |
| source | The source from which the indicator was obtained. Possible values are: manual, automated, threat_intel, sandbox, enrichment, import. | Optional |
| source_reference | The free-form reference identifying the source (URL, ticket, report name, etc.). | Optional |
| valid_until | The ISO-8601 datetime after which to automatically invalidate the indicator, for example, “2026-12-31T00:00:00Z”. | Optional |
| decompose | Whether to auto-decompose the indicator (URL→domain, email→domain). Possible values are: true, false. Default is true. | Optional |
| publish | Whether to publish the indicator immediately after creation. Possible values are: true, false. Default is false. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.CaseIndicator.id | Number | The association ID. |
| DFIRe.CaseIndicator.indicator.id | Number | The indicator ID. |
| DFIRe.CaseIndicator.indicator.value | String | The indicator value. |
dfire-case-indicator-remove
Removes an indicator association from a case.
Base Command
dfire-case-indicator-remove
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The case ID. | Required |
| association_id | The case indicator association ID. | Required |
Context Output
There is no context output for this command.
dfire-ioc-extract
Extracts candidate IOCs from a block of text. Returns suggestions only — does not add them to any case.
Base Command
dfire-ioc-extract
Input
| Argument Name | Description | Required |
|---|---|---|
| text | The text to scan to extract indicators from. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.IOCExtraction.candidates | Unknown | The list of extracted indicator candidates. |
dfire-indicator-check
Batch-checks whether IOCs already exist in the global registry.
Base Command
dfire-indicator-check
Input
| Argument Name | Description | Required |
|---|---|---|
| indicators | The JSON array of {value, stix_type} objects (mutually exclusive with values+stix_type). | Optional |
| values | A comma-separated indicator values to check (used with stix_type). | Optional |
| stix_type | The STIX type to use when checking the values argument. Possible values are: ipv4-addr, ipv6-addr, domain-name, url, email-addr, email-message, file, process, windows-registry-key, network-traffic, user-account, mac-addr, software, artifact, autonomous-system, directory, mutex, x509-certificate. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.IndicatorCheck.results | Unknown | The status and details of each submitted indicator. |
dfire-indicator-enrich
Triggers external enrichment for an indicator.
Base Command
dfire-indicator-enrich
Input
| Argument Name | Description | Required |
|---|---|---|
| indicator_id | The indicator ID. | Required |
| providers | A comma-separated list of provider names (omit this to run all providers). | Optional |
| force | Whether to re-enrich even if cached results exist. Possible values are: true, false. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.Indicator.id | Number | The indicator ID. |
dfire-indicator-enrichment-list
Retrieves cached enrichment results for an indicator.
Base Command
dfire-indicator-enrichment-list
Input
| Argument Name | Description | Required |
|---|---|---|
| indicator_id | The indicator ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.Enrichment.enrichments | Unknown | The enrichment records. |
dfire-indicator-publish
Publishes an indicator (making it visible to TAXII consumers and STIX exports).
Base Command
dfire-indicator-publish
Input
| Argument Name | Description | Required |
|---|---|---|
| indicator_id | The indicator ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.Indicator.id | Number | The DFIRe indicator ID. |
| DFIRe.Indicator.is_published | Boolean | Whether the indicator is published. |
dfire-indicator-unpublish
Unpublishes an indicator.
Base Command
dfire-indicator-unpublish
Input
| Argument Name | Description | Required |
|---|---|---|
| indicator_id | The indicator ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.Indicator.id | Number | The DFIRe indicator ID. |
| DFIRe.Indicator.is_published | Boolean | Whether the indicator is published. |
dfire-indicator-revoke
Revokes an indicator.
Base Command
dfire-indicator-revoke
Input
| Argument Name | Description | Required |
|---|---|---|
| indicator_id | The indicator ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.Indicator.id | Number | The DFIRe indicator ID. |
| DFIRe.Indicator.is_revoked | Boolean | Whether the indicator is revoked. |
dfire-indicator-unrevoke
Unrevokes an indicator.
Base Command
dfire-indicator-unrevoke
Input
| Argument Name | Description | Required |
|---|---|---|
| indicator_id | The indicator ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.Indicator.id | Number | The DFIRe indicator ID. |
| DFIRe.Indicator.is_revoked | Boolean | Whether the indicator is revoked. |
dfire-indicator-decompose
Auto-decomposes an indicator (URL→domain, email→domain, etc.).
Base Command
dfire-indicator-decompose
Input
| Argument Name | Description | Required |
|---|---|---|
| indicator_id | The indicator ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.Indicator.id | Number | The DFIRe indicator ID. |
dfire-indicator-add-tags
Merges a list of tags into the indicator’s existing tag set.
Base Command
dfire-indicator-add-tags
Input
| Argument Name | Description | Required |
|---|---|---|
| indicator_id | The indicator ID. | Required |
| tags | A comma-separated list of tags to add. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.Indicator.id | Number | The DFIRe indicator ID. |
| DFIRe.Indicator.tags | Unknown | The updated tag list. |
dfire-indicator-correlated-list
Lists indicators that appear in multiple cases.
Base Command
dfire-indicator-correlated-list
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.IndicatorCorrelated.results | Unknown | The indicators correlated across cases. |
dfire-indicator-bulk-classify
Bulk-updates classification for multiple indicators.
Base Command
dfire-indicator-bulk-classify
Input
| Argument Name | Description | Required |
|---|---|---|
| indicator_ids | A comma-separated list of indicator IDs. | Required |
| classification | The new indicator classification. Possible values are: unknown, benign, suspicious, malicious. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.BulkResult | Unknown | The bulk operation result. |
dfire-indicator-bulk-confidence
The bulk-update confidence for multiple indicators.
Base Command
dfire-indicator-bulk-confidence
Input
| Argument Name | Description | Required |
|---|---|---|
| indicator_ids | A comma-separated list of indicator IDs. | Required |
| confidence | The new indicator confidence level. Possible values are: low, medium, high. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.BulkResult | Unknown | The bulk operation result. |
dfire-indicator-bulk-tag
Bulk adds/removes/sets tags on multiple indicators.
Base Command
dfire-indicator-bulk-tag
Input
| Argument Name | Description | Required |
|---|---|---|
| indicator_ids | A comma-separated list of indicator IDs. | Required |
| tags | A comma-separated list of indicator tags. | Required |
| mode | The action to perform on the tags (add, remove, set). Possible values are: add, remove, set. Default is add. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.BulkResult | Unknown | The bulk operation result. |
dfire-indicator-bulk-tlp
Bulk-updates TLP designation for multiple indicators.
Base Command
dfire-indicator-bulk-tlp
Input
| Argument Name | Description | Required |
|---|---|---|
| indicator_ids | A comma-separated list of indicator IDs. | Required |
| tlp | The new indicator TLP designation. Possible values are: clear, green, amber, amber_strict, red. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.BulkResult | Unknown | The bulk operation result. |
dfire-indicator-bulk-publish
Bulk-publishes indicators.
Base Command
dfire-indicator-bulk-publish
Input
| Argument Name | Description | Required |
|---|---|---|
| indicator_ids | A comma-separated list of indicator IDs. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.BulkPublishResponse.published_count | Number | The number of indicators published. |
| DFIRe.BulkPublishResponse.skipped_revoked | Number | The number of indicators skipped because they were revoked. |
| DFIRe.BulkPublishResponse.skipped_red | Number | The number of indicators skipped because of TLP status RED. |
dfire-indicator-bulk-revoke
Bulk-revokes indicators.
Base Command
dfire-indicator-bulk-revoke
Input
| Argument Name | Description | Required |
|---|---|---|
| indicator_ids | A comma-separated list of indicator IDs. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.BulkResult | Unknown | The bulk operation result. |
dfire-indicator-bulk-delete
Bulk-deletes indicators.
Base Command
dfire-indicator-bulk-delete
Input
| Argument Name | Description | Required |
|---|---|---|
| indicator_ids | A comma-separated list of indicator IDs. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.BulkResult | Unknown | The bulk operation result. |
dfire-case-generate-summary
Triggers an AI-generated executive summary for a case.
Base Command
dfire-case-generate-summary
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The case ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.CaseSummary | Unknown | The summary result. |
dfire-case-chat
Sends a chat message to the case AI assistant.
Base Command
dfire-case-chat
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The case ID. | Required |
| message | The user message to send. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.CaseChat | Unknown | The chat response. |
dfire-case-update-report
Updates the text of an AI-generated report attached to a case (e.g. an executive summary).
Base Command
dfire-case-update-report
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The case ID the report belongs to. | Required |
| report_id | The ID of the generated report to update. | Required |
| report_text | The new report text content. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.CaseReport | Unknown | The updated report. |
dfire-case-can-report-list
Lists CAN (Case Activity Notice) reports for a case.
Base Command
dfire-case-can-report-list
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The case ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.CANReport.id | Number | The CAN report ID. |
dfire-case-can-report-generate
Generates a new CAN report for a case.
Base Command
dfire-case-can-report-generate
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The case ID. | Required |
| body | The optional JSON body describing the report parameters. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.CANReport.id | Number | The generated report ID. |
dfire-case-investigation-report-get
Retrieves the investigation report for a case.
Base Command
dfire-case-investigation-report-get
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The case ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.InvestigationReport | Unknown | The investigation report. |
dfire-case-investigation-report-generate
Generates AI content for a single section of a case’s investigation report. Returns preview content; does not auto-save.
Base Command
dfire-case-investigation-report-generate
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The case ID. | Required |
| section_id | The ID of the report section to generate content for. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.InvestigationReport.content | String | The generated section content. |
| DFIRe.InvestigationReport.model | String | The model used to generate the content. |
dfire-case-investigation-report-finalize
Finalizes the investigation report for a case.
Base Command
dfire-case-investigation-report-finalize
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The case ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.InvestigationReport | Unknown | The finalized investigation report. |
dfire-case-investigation-report-ready-for-qa
Marks a single section of the investigation report as ready for QA review.
Base Command
dfire-case-investigation-report-ready-for-qa
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The case ID. | Required |
| section_id | The ID of the report section to mark ready for QA. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.InvestigationReport | Unknown | The investigation report section after the state change. |
dfire-case-timeline-change-phase
Moves a case to a new response phase in the timeline.
Base Command
dfire-case-timeline-change-phase
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The case ID. | Required |
| phase_id | The target phase ID. | Optional |
| phase_name | The target phase name (used if phase_id is omitted). | Optional |
| note | The optional note explaining the phase change. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.TimelineEvent.id | Number | The created phase change timeline event ID. |
dfire-case-todo-list
Lists todos for a case.
Base Command
dfire-case-todo-list
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The case ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.CaseTodo.id | Number | The todo ID. |
| DFIRe.CaseTodo.title | String | The todo title. |
| DFIRe.CaseTodo.status | String | The todo status. |
dfire-case-todo-get
Retrieves a single todo with full details.
Base Command
dfire-case-todo-get
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The case ID. | Required |
| todo_id | The todo ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.CaseTodo.id | Number | The todo ID. |
dfire-case-todo-assign
Assigns a todo to a user.
Base Command
dfire-case-todo-assign
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The case ID. | Required |
| todo_id | The todo ID. | Required |
| user_id | The user ID of the assignee. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.CaseTodo.id | Number | The todo ID. |
| DFIRe.CaseTodo.assignee_name | String | The assignee display name. |
dfire-case-todo-note-set
Sets or replaces the note on a todo.
Base Command
dfire-case-todo-note-set
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The case ID. | Required |
| todo_id | The todo ID. | Required |
| note | The new note content. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.CaseTodo.id | Number | The todo ID. |
dfire-case-todo-attach-runbook
Attaches a runbook to a todo.
Base Command
dfire-case-todo-attach-runbook
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The case ID. | Required |
| todo_id | The todo ID. | Required |
| runbook_slug | The runbook slug to attach. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.CaseTodo.id | Number | The todo ID. |
| DFIRe.CaseTodo.runbook_slug | String | The attached runbook slug. |
dfire-case-todo-detach-runbook
Detaches the runbook from a todo.
Base Command
dfire-case-todo-detach-runbook
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The case ID. | Required |
| todo_id | The todo ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.CaseTodo.id | Number | The todo ID. |
dfire-case-timer-list
Lists the SLA timers for a case.
Base Command
dfire-case-timer-list
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The case ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.CaseTimer.id | Number | The timer ID. |
| DFIRe.CaseTimer.name | String | The timer name. |
| DFIRe.CaseTimer.framework | String | The compliance framework. |
dfire-case-timer-get
Retrieves a single SLA timer.
Base Command
dfire-case-timer-get
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The case ID. | Required |
| timer_id | The timer ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.CaseTimer.id | Number | The timer ID. |
dfire-case-timer-complete
Marks a case SLA timer as complete.
Base Command
dfire-case-timer-complete
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The case ID. | Required |
| timer_id | The timer ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.CaseTimer.id | Number | The timer ID. |
dfire-case-timer-reset
Resets a case SLA timer.
Base Command
dfire-case-timer-reset
Input
| Argument Name | Description | Required |
|---|---|---|
| case_id | The case ID. | Required |
| timer_id | The timer ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.CaseTimer.id | Number | The timer ID. |
dfire-case-get-by-number
Looks up a case by its human-readable case number.
Base Command
dfire-case-get-by-number
Input
| Argument Name | Description | Required |
|---|---|---|
| case_number | The case number (e.g. “CASE-2026-0001”). | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.Case.id | Number | The case ID. |
| DFIRe.Case.case_number | String | The case number. |
dfire-item-resolve-short-id
Resolves an 8-character item short ID to its full UUID and parent case ID.
Base Command
dfire-item-resolve-short-id
Input
| Argument Name | Description | Required |
|---|---|---|
| short_id | The first 8 characters of the item UUID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.Item.uuid | String | The full item UUID. |
| DFIRe.Item.case | Number | The parent case ID. |
dfire-incident-category-list
Lists ENISA incident categories (useful for picklists).
Base Command
dfire-incident-category-list
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.IncidentCategory.id | Number | The category ID. |
| DFIRe.IncidentCategory.name | String | The category name. |
dfire-incident-phase-list
Lists configured incident-response phases.
Base Command
dfire-incident-phase-list
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.IncidentPhase.id | Number | The phase ID. |
| DFIRe.IncidentPhase.name | String | The phase name. |
dfire-outcome-verdict-list
Lists case outcome verdicts (true positive, false positive, etc.).
Base Command
dfire-outcome-verdict-list
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.OutcomeVerdict.id | Number | The verdict ID. |
| DFIRe.OutcomeVerdict.name | String | The verdict name. |
dfire-project-list
Lists projects.
Base Command
dfire-project-list
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.Project.id | Number | The project ID. |
| DFIRe.Project.name | String | The project name. |
dfire-runbook-list
Lists available runbooks (used for todo runbook attachments).
Base Command
dfire-runbook-list
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.Runbook.slug | String | The runbook slug. |
| DFIRe.Runbook.name | String | The runbook name. |
dfire-group-list
Lists user groups.
Base Command
dfire-group-list
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| DFIRe.Group.id | Number | The user group ID. |
| DFIRe.Group.name | String | The user group name. |
Configuration parameters
url— Server URL (required)apikey— API Key (required)proxy— Use system proxy settingsinsecure— Trust any certificate (not secure)
Commands (75)
-
dfire-attachment-deleteDeletes an attachment.
-
dfire-attachment-getGets details of a specific attachment.
-
dfire-attachment-listLists attachments, optionally filtered by evidence item UUID.
-
dfire-attachment-uploadUploads a file as an attachment to a case or evidence item.
-
dfire-case-can-report-generateGenerates a new CAN report for a case.
-
dfire-case-can-report-listLists CAN (Case Activity Notice) reports for a case.
-
dfire-case-chatSends a chat message to the case AI assistant.
-
dfire-case-createCreates a new case in DFIRe.
-
dfire-case-deleteDeletes a case from DFIRe.
-
dfire-case-generate-summaryTriggers an AI-generated executive summary for a case.
-
dfire-case-getRetrieves details of a specific case.
-
dfire-case-get-by-numberLooks up a case by its human-readable case number.
-
dfire-case-indicator-addAdds an indicator to a case. Creates the indicator if it does not exist.
-
dfire-case-indicator-listLists indicators associated with a case.
-
dfire-case-indicator-removeRemoves an indicator association from a case.
-
dfire-case-investigation-report-finalizeFinalizes the investigation report for a case.
-
dfire-case-investigation-report-generateGenerates AI content for a single section of a case's investigation report. Returns preview content; does not auto-save.
-
dfire-case-investigation-report-getRetrieves the investigation report for a case.
-
dfire-case-investigation-report-ready-for-qaMarks a single section of the investigation report as ready for QA review.
-
dfire-case-listLists cases from DFIRe.
-
dfire-case-note-createCreates a note on a case.
-
dfire-case-note-listLists notes for a case.
-
dfire-case-timeline-change-phaseMoves a case to a new response phase in the timeline.
-
dfire-case-timer-completeMarks a case SLA timer as complete.
-
dfire-case-timer-getRetrieves a single SLA timer.
-
dfire-case-timer-listLists the SLA timers for a case.
-
dfire-case-timer-resetResets a case SLA timer.
-
dfire-case-todo-assignAssigns a todo to a user.
-
dfire-case-todo-attach-runbookAttaches a runbook to a todo.
-
dfire-case-todo-detach-runbookDetaches the runbook from a todo.
-
dfire-case-todo-getRetrieves a single todo with full details.
-
dfire-case-todo-listLists todos for a case.
-
dfire-case-todo-note-setSets or replaces the note on a todo.
-
dfire-case-type-listLists available case types and their IDs.
-
dfire-case-updateUpdates an existing case in DFIRe.
-
dfire-case-update-reportUpdates the text of an AI-generated report attached to a case (e.g. an executive summary).
-
dfire-group-listLists user groups.
-
dfire-incident-category-listLists ENISA incident categories (useful for picklists).
-
dfire-incident-phase-listLists configured incident-response phases.
-
dfire-indicator-add-tagsMerges a list of tags into the indicator's existing tag set.
-
dfire-indicator-bulk-classifyBulk-updates classification for multiple indicators.
-
dfire-indicator-bulk-confidenceThe bulk-update confidence for multiple indicators.
-
dfire-indicator-bulk-deleteBulk-deletes indicators.
-
dfire-indicator-bulk-publishBulk-publishes indicators.
-
dfire-indicator-bulk-revokeBulk-revokes indicators.
-
dfire-indicator-bulk-tagBulk adds/removes/sets tags on multiple indicators.
-
dfire-indicator-bulk-tlpBulk-updates TLP designation for multiple indicators.
-
dfire-indicator-checkBatch-checks whether IOCs already exist in the global registry.
-
dfire-indicator-correlated-listLists indicators that appear in multiple cases.
-
dfire-indicator-createCreates a new indicator in the global IOC registry.
-
dfire-indicator-decomposeAuto-decomposes an indicator (URL→domain, email→domain, etc.).
-
dfire-indicator-deleteDeletes an indicator from the global IOC registry.
-
dfire-indicator-enrichTriggers external enrichment for an indicator.
-
dfire-indicator-enrichment-listRetrieves cached enrichment results for an indicator.
-
dfire-indicator-getRetrieves details of a specific indicator.
-
dfire-indicator-listLists indicators from the global IOC registry.
-
dfire-indicator-publishPublishes an indicator (making it visible to TAXII consumers and STIX exports).
-
dfire-indicator-revokeRevokes an indicator.
-
dfire-indicator-unpublishUnpublishes an indicator.
-
dfire-indicator-unrevokeUnrevokes an indicator.
-
dfire-indicator-updateUpdates an existing indicator.
-
dfire-ioc-extractExtracts candidate IOCs from a block of text. Returns suggestions only — does not add them to any case.
-
dfire-item-createCreates a new evidence item on a case.
-
dfire-item-flag-listLists available item flags and their IDs.
-
dfire-item-getRetrieves details of a specific evidence item.
-
dfire-item-listLists evidence items, optionally filtered by case.
-
dfire-item-resolve-short-idResolves an 8-character item short ID to its full UUID and parent case ID.
-
dfire-item-type-listLists available evidence item types and their IDs.
-
dfire-outcome-verdict-listLists case outcome verdicts (true positive, false positive, etc.).
-
dfire-project-listLists projects.
-
dfire-runbook-listLists available runbooks (used for todo runbook attachments).
-
dfire-searchSearches across all DFIRe data (cases, indicators, notes, items). Supports AND, OR, NOT operators.
-
dfire-timeline-createAdds a manual timeline event to a case.
-
dfire-timeline-listLists timeline events for a case (newest first).
-
dfire-user-listLists users in the DFIRe tenant. Useful for looking up user IDs for assignments.
"""Unit tests for the DFIRe integration. Each test mocks `Client._http_request` and asserts both the outbound request shape (method, URL, body / params) and the resulting `CommandResults`. Many command families share a single parametrised test to keep the suite compact. """ import pytest import DFIRe BASE_URL = "https://dfire.test/api" # disable-secrets-detection @pytest.fixture def client(mocker): """A Client whose `_http_request` is a MagicMock the tests drive directly.""" c = DFIRe.Client( base_url=BASE_URL, verify=False, headers={"Authorization": "Bearer dfire_ak_test"}, proxy=False, ) mocker.patch.object(c, "_http_request") return c # ── Helper-function tests ───────────────────────────────── def test_build_optional_body_filters_none(): args = {"a": "v", "b": None, "c": 0, "d": False, "e": ""} body = DFIRe.build_optional_body(args, ["a", "b", "c", "d", "e", "missing"]) # build_optional_body uses `is not None` so 0, False, "" all survive. assert body == {"a": "v", "c": 0, "d": False, "e": ""} def test_extract_case_todos_handles_list(client): client._http_request.return_value = {"todo_checklist": [{"id": "t1"}, {"id": "t2"}]} assert DFIRe._extract_case_todos(client, 5) == [{"id": "t1"}, {"id": "t2"}] def test_extract_case_todos_handles_nested_results(client): client._http_request.return_value = {"todo_checklist": {"results": [{"id": "t1"}]}} assert DFIRe._extract_case_todos(client, 5) == [{"id": "t1"}] def test_extract_case_todos_handles_missing(client): client._http_request.return_value = {} assert DFIRe._extract_case_todos(client, 5) == [] # ── test-module ─────────────────────────────────────────── def test_test_module(client): client._http_request.return_value = {"results": []} assert DFIRe.test_module(client) == "ok" args, kwargs = client._http_request.call_args assert args[0] == "GET" assert args[1] == "/cases/" # ── Search ──────────────────────────────────────────────── def test_search_command(client): client._http_request.return_value = {"results": [{"id": 1, "type": "case", "title": "T"}]} result = DFIRe.search_command(client, {"query": "test"}) args, kwargs = client._http_request.call_args assert args == ("GET", "/search/") assert kwargs["params"] == {"q": "test"} assert result.outputs_prefix == "DFIRe.Search" # ── Cases — list/get/create/update/delete ──────────────── def test_case_list_passes_all_filters(client): client._http_request.return_value = {"results": []} DFIRe.case_list_command( client, { "limit": "25", "page": "2", "status": "OPEN", "status_in": "OPEN,CLOSED", "severity": "high", "case_mode": "incident", "lead_investigator": "7", "created_at_gte": "2026-01-01T00:00:00Z", "created_at_lte": "2026-12-31T23:59:59Z", "ordering": "-created_at", }, ) args, kwargs = client._http_request.call_args assert args == ("GET", "/cases/") p = kwargs["params"] assert p["page_size"] == 25 assert p["page"] == 2 assert p["status"] == "OPEN" assert p["status__in"] == "OPEN,CLOSED" assert p["severity"] == "high" assert p["case_mode"] == "incident" assert p["lead_investigator"] == 7 assert p["created_at__gte"] == "2026-01-01T00:00:00Z" assert p["created_at__lte"] == "2026-12-31T23:59:59Z" assert p["ordering"] == "-created_at" def test_case_get(client): client._http_request.return_value = {"id": 1, "case_number": "CASE-1"} result = DFIRe.case_get_command(client, {"case_id": "1"}) assert client._http_request.call_args.args == ("GET", "/cases/1/") assert result.outputs["id"] == 1 def test_case_create_defaults_slack_channel_false(client): client._http_request.return_value = {"id": 9} DFIRe.case_create_command(client, {"title": "T", "case_type": "6"}) body = client._http_request.call_args.kwargs["json_data"] assert body["title"] == "T" assert body["case_type"] == 6 # The whole point of v1.1.0: SOAR-created cases do not spawn Slack channels by default. assert body["create_slack_channel"] is False def test_case_create_allows_slack_channel_opt_in(client): client._http_request.return_value = {"id": 9} DFIRe.case_create_command(client, {"title": "T", "case_type": "6", "create_slack_channel": "true"}) assert client._http_request.call_args.kwargs["json_data"]["create_slack_channel"] is True def test_case_create_propagates_new_fields(client): client._http_request.return_value = {"id": 9} DFIRe.case_create_command( client, { "title": "T", "case_type": "6", "notes": "N", "lead_investigator": "3", "investigators": "1,2,3", "viewers": "4,5", "incident_category": "2", "outcome_verdict": "1", "attributes": '{"k":"v"}', }, ) body = client._http_request.call_args.kwargs["json_data"] assert body["notes"] == "N" assert body["lead_investigator"] == 3 assert body["investigators"] == [1, 2, 3] assert body["viewers"] == [4, 5] assert body["incident_category"] == 2 assert body["outcome_verdict"] == 1 assert body["attributes"] == {"k": "v"} def test_case_update_requires_at_least_one_field(client): with pytest.raises(DFIRe.DemistoException, match="At least one field"): DFIRe.case_update_command(client, {"case_id": "1"}) def test_case_update_sends_patch_with_partial_body(client): client._http_request.return_value = {"id": 1} DFIRe.case_update_command(client, {"case_id": "1", "title": "New", "investigators": "1,2"}) args, kwargs = client._http_request.call_args assert args == ("PATCH", "/cases/1/") assert kwargs["json_data"] == {"title": "New", "investigators": [1, 2]} def test_case_delete(client): DFIRe.case_delete_command(client, {"case_id": "1"}) args, kwargs = client._http_request.call_args assert args == ("DELETE", "/cases/1/") assert kwargs["resp_type"] == "response" def test_case_get_by_number(client): client._http_request.return_value = {"id": 1, "case_number": "CASE-1"} DFIRe.case_get_by_number_command(client, {"case_number": "CASE-2026-001"}) assert client._http_request.call_args.args == ("GET", "/case/CASE-2026-001/") # ── Case notes / timeline ───────────────────────────────── def test_case_note_list(client): client._http_request.return_value = [{"id": 1}] DFIRe.case_note_list_command(client, {"case_id": "1"}) args, kwargs = client._http_request.call_args assert args == ("GET", "/case-notes/") assert kwargs["params"] == {"case": 1} def test_case_note_create(client): client._http_request.return_value = {"id": 2} DFIRe.case_note_create_command(client, {"case_id": "1", "note": "hi", "show_on_timeline": "true"}) body = client._http_request.call_args.kwargs["json_data"] assert body == {"case": 1, "note": "hi", "show_on_timeline": True} def test_timeline_list(client): client._http_request.return_value = {"events": []} DFIRe.timeline_list_command(client, {"case_id": "1"}) assert client._http_request.call_args.args == ("GET", "/cases/1/timeline/") def test_timeline_create_defaults_event_datetime(client): """The API requires event_datetime; the integration must inject a default when omitted.""" client._http_request.return_value = {"id": 1} DFIRe.timeline_create_command(client, {"case_id": "1", "subject": "S"}) body = client._http_request.call_args.kwargs["json_data"] assert "event_datetime" in body assert body["event_datetime"].endswith("Z") assert body["subject"] == "S" def test_timeline_create_uses_supplied_event_datetime(client): client._http_request.return_value = {"id": 1} DFIRe.timeline_create_command(client, {"case_id": "1", "subject": "S", "event_datetime": "2026-05-01T10:00:00Z"}) body = client._http_request.call_args.kwargs["json_data"] assert body["event_datetime"] == "2026-05-01T10:00:00Z" def test_case_timeline_change_phase(client): client._http_request.return_value = {"id": 1} DFIRe.case_timeline_change_phase_command(client, {"case_id": "1", "phase_id": "3", "note": "Move on"}) args, kwargs = client._http_request.call_args assert args == ("POST", "/cases/1/timeline/change-phase/") assert kwargs["json_data"] == {"phase_id": 3, "note": "Move on"} # ── Indicators ──────────────────────────────────────────── def test_indicator_list_passes_all_filters(client): client._http_request.return_value = {"results": []} DFIRe.indicator_list_command( client, { "limit": "100", "offset": "10", "search": "term", "stix_type": "domain-name", "classification": "suspicious", "confidence": "high", "tlp": "amber", "is_published": "true", "is_revoked": "false", "parent": "5", "ordering": "-created_at", }, ) p = client._http_request.call_args.kwargs["params"] assert p["limit"] == 100 assert p["offset"] == 10 assert p["search"] == "term" assert p["parent"] == 5 assert p["ordering"] == "-created_at" def test_indicator_get(client): client._http_request.return_value = {"id": 42, "value": "8.8.8.8", "stix_type": "ipv4-addr"} result = DFIRe.indicator_get_command(client, {"indicator_id": "42"}) assert client._http_request.call_args.args == ("GET", "/indicators/42/") assert result.outputs["id"] == 42 assert result.outputs["value"] == "8.8.8.8" def test_indicator_create(client): client._http_request.return_value = {"id": 1, "is_existing": False} DFIRe.indicator_create_command(client, {"value": "1.2.3.4", "stix_type": "ipv4-addr", "tags": "a,b"}) args, kwargs = client._http_request.call_args assert args == ("POST", "/indicators/") assert kwargs["json_data"]["tags"] == ["a", "b"] assert kwargs["ok_codes"] == (200, 201) def test_indicator_update_requires_field(client): with pytest.raises(DFIRe.DemistoException): DFIRe.indicator_update_command(client, {"indicator_id": "1"}) def test_indicator_delete(client): DFIRe.indicator_delete_command(client, {"indicator_id": "1"}) assert client._http_request.call_args.args == ("DELETE", "/indicators/1/") @pytest.mark.parametrize( "command_fn,sub_path,action_label", [ (DFIRe.indicator_publish_command, "publish", "Published"), (DFIRe.indicator_unpublish_command, "unpublish", "Unpublished"), (DFIRe.indicator_revoke_command, "revoke", "Revoked"), (DFIRe.indicator_unrevoke_command, "unrevoke", "Unrevoked"), (DFIRe.indicator_decompose_command, "decompose", "Decomposed"), ], ) def test_indicator_lifecycle_commands(client, command_fn, sub_path, action_label): client._http_request.return_value = {"id": 1, sub_path: True} result = command_fn(client, {"indicator_id": "1"}) args, kwargs = client._http_request.call_args assert args == ("POST", f"/indicators/1/{sub_path}/") assert kwargs["json_data"] == {} assert action_label in result.readable_output def test_indicator_add_tags(client): client._http_request.return_value = {"id": 1, "tags": ["a", "b"]} DFIRe.indicator_add_tags_command(client, {"indicator_id": "1", "tags": "a,b"}) args, kwargs = client._http_request.call_args assert args == ("POST", "/indicators/1/add-tags/") assert kwargs["json_data"] == {"tags": ["a", "b"]} def test_indicator_add_tags_requires_tags(client): with pytest.raises(DFIRe.DemistoException, match="tags"): DFIRe.indicator_add_tags_command(client, {"indicator_id": "1", "tags": ""}) def test_indicator_enrich(client): client._http_request.return_value = {"id": 1} DFIRe.indicator_enrich_command(client, {"indicator_id": "1", "providers": "dns,whois", "force": "true"}) body = client._http_request.call_args.kwargs["json_data"] assert body == {"providers": ["dns", "whois"], "force": True} def test_indicator_enrichment_list(client): client._http_request.return_value = {"enrichments": []} DFIRe.indicator_enrichment_list_command(client, {"indicator_id": "1"}) assert client._http_request.call_args.args == ("GET", "/indicators/1/enrichments/") def test_indicator_correlated_list(client): client._http_request.return_value = {"results": []} DFIRe.indicator_correlated_list_command(client, {}) assert client._http_request.call_args.args == ("GET", "/indicators/correlated/") def test_ioc_extract(client): client._http_request.return_value = {"candidates": [{"value": "1.2.3.4", "stix_type": "ipv4-addr"}]} DFIRe.ioc_extract_command(client, {"text": "see 1.2.3.4"}) args, kwargs = client._http_request.call_args assert args == ("POST", "/ioc/extract/") assert kwargs["json_data"] == {"text": "see 1.2.3.4"} def test_indicator_check_with_values_arg(client): client._http_request.return_value = {"results": [{"value": "1.2.3.4", "exists": False}]} DFIRe.indicator_check_command(client, {"values": "1.2.3.4,5.6.7.8", "stix_type": "ipv4-addr"}) body = client._http_request.call_args.kwargs["json_data"] assert body == { "indicators": [ {"value": "1.2.3.4", "stix_type": "ipv4-addr"}, {"value": "5.6.7.8", "stix_type": "ipv4-addr"}, ] } def test_indicator_check_with_indicators_json(client): client._http_request.return_value = {"results": []} DFIRe.indicator_check_command(client, {"indicators": '[{"value":"a","stix_type":"domain-name"}]'}) body = client._http_request.call_args.kwargs["json_data"] assert body == {"indicators": [{"value": "a", "stix_type": "domain-name"}]} def test_indicator_check_requires_either_form(client): with pytest.raises(DFIRe.DemistoException): DFIRe.indicator_check_command(client, {}) # ── Bulk indicator commands (parametrised) ──────────────── @pytest.mark.parametrize( "command_fn,sub_path,extra_args,expected_extra", [ ( DFIRe.indicator_bulk_classify_command, "bulk-classify", {"classification": "malicious"}, {"classification": "malicious"}, ), ( DFIRe.indicator_bulk_confidence_command, "bulk-confidence", {"confidence": "high"}, {"confidence": "high"}, ), ( DFIRe.indicator_bulk_tag_command, "bulk-tag", {"tags": "a,b", "mode": "add"}, {"tags": ["a", "b"], "mode": "add"}, ), ( DFIRe.indicator_bulk_tlp_command, "bulk-tlp", {"tlp": "amber"}, {"tlp": "amber"}, ), (DFIRe.indicator_bulk_publish_command, "bulk-publish", {}, {}), (DFIRe.indicator_bulk_revoke_command, "bulk-revoke", {}, {}), (DFIRe.indicator_bulk_delete_command, "bulk-delete", {}, {}), ], ) def test_indicator_bulk_commands(client, command_fn, sub_path, extra_args, expected_extra): client._http_request.return_value = {"updated": 2} args = {"indicator_ids": "1,2", **extra_args} command_fn(client, args) call_args, call_kwargs = client._http_request.call_args assert call_args == ("POST", f"/indicators/{sub_path}/") body = call_kwargs["json_data"] assert body["indicator_ids"] == [1, 2] for k, v in expected_extra.items(): assert body[k] == v def test_indicator_bulk_classify_requires_classification(client): with pytest.raises(DFIRe.DemistoException): DFIRe.indicator_bulk_classify_command(client, {"indicator_ids": "1"}) def test_indicator_bulk_commands_reject_empty_ids(client): with pytest.raises(DFIRe.DemistoException, match="indicator_ids"): DFIRe.indicator_bulk_publish_command(client, {"indicator_ids": ""}) # ── Case indicators ─────────────────────────────────────── def test_case_indicator_list(client): client._http_request.return_value = [{"id": 1, "indicator": {"id": 9}}] DFIRe.case_indicator_list_command(client, {"case_id": "1"}) assert client._http_request.call_args.args == ("GET", "/cases/1/indicators/") def test_case_indicator_add_includes_new_fields(client): client._http_request.return_value = {"id": 5} DFIRe.case_indicator_add_command( client, { "case_id": "1", "value": "1.2.3.4", "stix_type": "ipv4-addr", "source": "automated", "valid_until": "2026-12-31T00:00:00Z", "publish": "true", "decompose": "false", "tags": "a,b", }, ) body = client._http_request.call_args.kwargs["json_data"] assert body["source"] == "automated" assert body["valid_until"] == "2026-12-31T00:00:00Z" assert body["publish"] is True assert body["decompose"] is False assert body["tags"] == ["a", "b"] def test_case_indicator_remove(client): DFIRe.case_indicator_remove_command(client, {"case_id": "1", "association_id": "2"}) args, kwargs = client._http_request.call_args assert args == ("DELETE", "/cases/1/indicators/2/") assert kwargs["resp_type"] == "response" # ── Items ───────────────────────────────────────────────── def test_item_get_accepts_uuid_string(client): """Regression: items have UUID ids; arg_to_number used to coerce and break this.""" uuid = "d9230268-8ad9-4d1d-812d-bee11c1c51ca" client._http_request.return_value = {"uuid": uuid, "name": "x"} DFIRe.item_get_command(client, {"item_id": uuid}) assert client._http_request.call_args.args == ("GET", f"/items/{uuid}/") def test_item_get_requires_item_id(client): with pytest.raises(DFIRe.DemistoException): DFIRe.item_get_command(client, {}) def test_item_resolve_short_id(client): client._http_request.return_value = {"uuid": "d9230268-..."} DFIRe.item_resolve_short_id_command(client, {"short_id": "d9230268"}) assert client._http_request.call_args.args == ("GET", "/item/d9230268/") def test_item_list(client): client._http_request.return_value = [{"uuid": "x"}] DFIRe.item_list_command(client, {"case_id": "1"}) args, kwargs = client._http_request.call_args assert args == ("GET", "/items/") assert kwargs["params"] == {"case": 1} def test_item_create(client): client._http_request.return_value = {"uuid": "x"} DFIRe.item_create_command( client, {"case_id": "1", "item_type": "19", "location": "loc", "name": "n"}, ) body = client._http_request.call_args.kwargs["json_data"] assert body["case"] == 1 assert body["item_type"] == 19 assert body["location"] == "loc" assert body["name"] == "n" # ── Attachments ─────────────────────────────────────────── def test_attachment_list(client): client._http_request.return_value = [{"id": 1}] DFIRe.attachment_list_command(client, {"item_uuid": "u"}) args, kwargs = client._http_request.call_args assert args == ("GET", "/attachments/") assert kwargs["params"] == {"item": "u"} def test_attachment_get(client): client._http_request.return_value = {"id": 1} DFIRe.attachment_get_command(client, {"attachment_id": "1"}) assert client._http_request.call_args.args == ("GET", "/attachments/1/") def test_attachment_delete(client): DFIRe.attachment_delete_command(client, {"attachment_id": "1"}) args, kwargs = client._http_request.call_args assert args == ("DELETE", "/attachments/1/") assert kwargs["resp_type"] == "response" def test_attachment_upload_orchestrates_init_chunks_complete(client, mocker, tmp_path): """Confirms the three-phase chunked upload calls init, upload, complete in order.""" sample = tmp_path / "blob.bin" sample.write_bytes(b"x" * 12) # demisto.getFilePath returns where the War Room file lives on disk. mocker.patch.object(DFIRe.demisto, "getFilePath", return_value={"path": str(sample), "name": "blob.bin"}) # init → upload (called per chunk) → complete client._http_request.side_effect = [ {"session_id": "sess", "chunk_size": 5}, # init: 5-byte chunks → 3 chunks for 12 bytes {"chunk_index": 0}, {"chunk_index": 1}, {"chunk_index": 2}, {"id": 99, "status": "processing"}, # complete ] DFIRe.attachment_upload_command(client, {"entry_id": "e1", "case_id": "1", "category": "general"}) calls = client._http_request.call_args_list assert calls[0].args == ("POST", "/attachments/chunked/init/") assert calls[1].args == ("POST", "/attachments/chunked/sess/upload/") assert calls[-1].args == ("POST", "/attachments/chunked/sess/complete/") # ── Users ───────────────────────────────────────────────── def test_user_list(client): client._http_request.return_value = [{"id": 1, "username": "admin"}] DFIRe.user_list_command(client, {}) assert client._http_request.call_args.args == ("GET", "/users/") # ── Case AI / reports ───────────────────────────────────── def test_case_generate_summary_uses_get_and_reads_text(client): """Regression: this endpoint is GET (not POST) and returns text/plain (not JSON).""" client._http_request.return_value = "Case Summary for CASE-1\n----\nstatus: OPEN" result = DFIRe.case_generate_summary_command(client, {"case_id": "1"}) args, kwargs = client._http_request.call_args assert args == ("GET", "/cases/1/generate-summary/") assert kwargs["resp_type"] == "text" assert result.outputs["summary"].startswith("Case Summary") def test_case_chat(client): client._http_request.return_value = {"reply": "ok"} DFIRe.case_chat_command(client, {"case_id": "1", "message": "hi"}) args, kwargs = client._http_request.call_args assert args == ("POST", "/cases/1/chat/") assert kwargs["json_data"] == {"message": "hi"} def test_case_update_report_uses_explicit_args(client): """v1.1.2: explicit report_id/report_text, not a raw body blob.""" client._http_request.return_value = {"ok": True} DFIRe.case_update_report_command(client, {"case_id": "1", "report_id": "5", "report_text": "new text"}) args, kwargs = client._http_request.call_args assert args == ("POST", "/cases/1/update-report/") assert kwargs["json_data"] == {"id": 5, "report_text": "new text"} def test_case_can_report_list(client): client._http_request.return_value = {"results": []} DFIRe.case_can_report_list_command(client, {"case_id": "1"}) assert client._http_request.call_args.args == ("GET", "/cases/1/can-reports/") def test_case_can_report_generate(client): client._http_request.return_value = {"id": 1} DFIRe.case_can_report_generate_command(client, {"case_id": "1"}) args, kwargs = client._http_request.call_args assert args == ("POST", "/cases/1/can-reports/generate/") assert kwargs["json_data"] == {} def test_case_investigation_report_get(client): client._http_request.return_value = {"id": 1} DFIRe.case_investigation_report_get_command(client, {"case_id": "1"}) assert client._http_request.call_args.args == ("GET", "/cases/1/investigation-report/") def test_case_investigation_report_generate_requires_section_id(client): with pytest.raises(KeyError): DFIRe.case_investigation_report_generate_command(client, {"case_id": "1"}) def test_case_investigation_report_generate_sends_section_id(client): client._http_request.return_value = {"content": "x"} DFIRe.case_investigation_report_generate_command(client, {"case_id": "1", "section_id": "8"}) args, kwargs = client._http_request.call_args assert args == ("POST", "/cases/1/investigation-report/generate/") assert kwargs["json_data"] == {"section_id": 8} def test_case_investigation_report_ready_for_qa_sends_section_id(client): client._http_request.return_value = {"id": 1} DFIRe.case_investigation_report_ready_for_qa_command(client, {"case_id": "1", "section_id": "13"}) args, kwargs = client._http_request.call_args assert args == ("POST", "/cases/1/investigation-report/ready-for-qa/") assert kwargs["json_data"] == {"section_id": 13} def test_case_investigation_report_finalize(client): client._http_request.return_value = {"id": 1} DFIRe.case_investigation_report_finalize_command(client, {"case_id": "1"}) args, kwargs = client._http_request.call_args assert args == ("POST", "/cases/1/investigation-report/finalize/") assert kwargs["json_data"] == {} # ── Todos ───────────────────────────────────────────────── def test_case_todo_list_derives_from_case(client): """Regression: API has no GET /todo/; the integration pulls them from case.todo_checklist.""" client._http_request.return_value = { "id": 1, "todo_checklist": [{"id": "u1", "title": "Triage"}], } result = DFIRe.case_todo_list_command(client, {"case_id": "1"}) assert client._http_request.call_args.args == ("GET", "/cases/1/") assert result.outputs == [{"id": "u1", "title": "Triage"}] def test_case_todo_get_filters_from_case(client): client._http_request.return_value = { "id": 1, "todo_checklist": [{"id": "u1", "title": "Triage"}, {"id": "u2", "title": "Contain"}], } result = DFIRe.case_todo_get_command(client, {"case_id": "1", "todo_id": "u2"}) assert result.outputs["title"] == "Contain" def test_case_todo_get_raises_when_missing(client): client._http_request.return_value = {"todo_checklist": []} with pytest.raises(DFIRe.DemistoException, match="No todo"): DFIRe.case_todo_get_command(client, {"case_id": "1", "todo_id": "u-missing"}) def test_case_todo_assign(client): client._http_request.return_value = {"status": "success"} DFIRe.case_todo_assign_command(client, {"case_id": "1", "todo_id": "u1", "user_id": "3"}) args, kwargs = client._http_request.call_args assert args == ("POST", "/cases/1/todo/u1/assign/") assert kwargs["json_data"] == {"user_id": 3} def test_case_todo_note_set_uses_put(client): """Regression: this endpoint is PUT (not POST).""" client._http_request.return_value = {"status": "success"} DFIRe.case_todo_note_set_command(client, {"case_id": "1", "todo_id": "u1", "note": "hello"}) args, kwargs = client._http_request.call_args assert args == ("PUT", "/cases/1/todo/u1/note/") assert kwargs["json_data"] == {"note": "hello"} def test_case_todo_attach_runbook(client): client._http_request.return_value = {"status": "success"} DFIRe.case_todo_attach_runbook_command(client, {"case_id": "1", "todo_id": "u1", "runbook_slug": "rb"}) args, kwargs = client._http_request.call_args assert args == ("POST", "/cases/1/todo/u1/attach-runbook/") assert kwargs["json_data"] == {"runbook_slug": "rb"} def test_case_todo_detach_runbook(client): client._http_request.return_value = {"status": "success"} DFIRe.case_todo_detach_runbook_command(client, {"case_id": "1", "todo_id": "u1"}) args, kwargs = client._http_request.call_args assert args == ("POST", "/cases/1/todo/u1/detach-runbook/") assert kwargs["json_data"] == {} # ── Timers ──────────────────────────────────────────────── def test_case_timer_list(client): client._http_request.return_value = {"results": []} DFIRe.case_timer_list_command(client, {"case_id": "1"}) assert client._http_request.call_args.args == ("GET", "/cases/1/timers/") def test_case_timer_get(client): client._http_request.return_value = {"id": 1} DFIRe.case_timer_get_command(client, {"case_id": "1", "timer_id": "2"}) assert client._http_request.call_args.args == ("GET", "/cases/1/timers/2/") @pytest.mark.parametrize( "command_fn,sub_path", [ (DFIRe.case_timer_complete_command, "complete"), (DFIRe.case_timer_reset_command, "reset"), ], ) def test_case_timer_actions(client, command_fn, sub_path): client._http_request.return_value = {"id": 1} command_fn(client, {"case_id": "1", "timer_id": "2"}) args, kwargs = client._http_request.call_args assert args == ("POST", f"/cases/1/timers/2/{sub_path}/") assert kwargs["json_data"] == {} # ── Reference-data list commands ────────────────────────── @pytest.mark.parametrize( "command_fn,endpoint", [ (DFIRe.case_type_list_command, "/case-types/"), (DFIRe.item_type_list_command, "/item-types/"), (DFIRe.item_flag_list_command, "/item-flags/"), (DFIRe.incident_category_list_command, "/incident-categories/"), (DFIRe.incident_phase_list_command, "/incident-phases/"), (DFIRe.outcome_verdict_list_command, "/outcome-verdicts/"), (DFIRe.project_list_command, "/projects/"), (DFIRe.runbook_list_command, "/runbooks/"), (DFIRe.group_list_command, "/groups/"), ], ) def test_reference_data_list_commands(client, command_fn, endpoint): client._http_request.return_value = [{"id": 1, "name": "x"}] command_fn(client, {}) assert client._http_request.call_args.args == ("GET", endpoint)