id: cortex_xdr
name: Cortex XDR
version: 1.2.0
description: "Palo Alto Cortex XDR (public API v1) — incident ingestion + write-back, endpoint isolation/scan/delete/tagging, RTR scripts, hash block/allow lists, file quarantine/restore/retrieval, alert exclusions, external alert push (parsed/CEF), device-control violations, audits, distributions and RBAC/risk."
changelog: "1.2.0 — Incident write-back (update_incident: status/severity/assignment/resolve comment) and external alert push (insert_parsed_alerts, insert_cef_alerts). 1.1.0 — Full command coverage: added delete/alias/tag endpoints, abort scan, original alerts, script metadata/code/snippet/exec-status, file retrieval (+details), alert exclusions, device-control violations, audits, distribution url/status/create and RBAC (users, roles, groups, risk score, risky users/hosts). 1.0.0 — Initial release: incident ingestion (get_incidents) with OCSF mapper, endpoints, isolate/unisolate, scan, hash blocklist/allowlist, quarantine/restore, run script + results, alerts retrieval, distributions and action status. Standard or Advanced API authentication."
category: endpoint

# Per-instance configuration. The base URL is the tenant API root, e.g.
# https://api-yourtenant.xdr.eu.paloaltonetworks.com  (scripts append /public_api/v1).
config_schema:
  properties:
    url:
      type: string
      description: "Cortex XDR API base URL, e.g. https://api-<tenant>.xdr.<region>.paloaltonetworks.com"
    api_key_id:
      type: string
      description: "API Key ID (the integer ID shown next to the API key in Settings → API Keys)"
    api_key:
      type: string
      description: "API Key secret"
      x-soar-sensitive: true
    auth_type:
      type: string
      description: "Authentication method: standard (key sent as-is) or advanced (nonce + timestamp SHA-256 hash)"
      default: standard
  required:
    - url
    - api_key_id
    - api_key

# Documented for reference; the bundled scripts build the headers themselves.
# Standard:  x-xdr-auth-id: <id>, Authorization: <api_key>
# Advanced:  x-xdr-auth-id: <id>, x-xdr-nonce, x-xdr-timestamp,
#            Authorization: sha256(api_key + nonce + timestamp)
auth:
  - id: apikey
    type: api_key
    in: header
    name: Authorization
    value_template: "{{secret}}"
    secret_field: api_key

commands:
  # ── Ingestion ─────────────────────────────────────────────────────────────
  - id: get_incidents
    name: cortex-xdr-get-incidents
    description: "Fetch Cortex XDR incidents for ingestion. Returns {reply:{incidents:[...]}}; use reply.incidents as the alert rule results path."
    risk: read
    inputs_schema:
      properties:
        status: { type: string, description: "Filter by status (e.g. new, under_investigation, resolved_threat_handled)" }
        created_after: { type: string, description: "Lower bound on creation_time, ISO8601 or epoch ms (incremental fetch watermark)" }
        limit: { type: number, description: "Maximum incidents to fetch (default 100)" }
      required: []
    outputs_schema: { properties: {} }
    ingest:
      results_path: reply.incidents
      dedup_key: incident_id
      incremental_field: created_after
  - id: get_incident_extra_data
    name: cortex-xdr-get-incident-extra-data
    description: "Get full incident data including its alerts and network artifacts by incident ID."
    risk: read
    inputs_schema:
      properties:
        incident_id: { type: string, description: "Incident ID" }
        alerts_limit: { type: number, description: "Max alerts to return (default 1000)" }
      required: [incident_id]
    outputs_schema: { properties: {} }
  - id: update_incident
    name: cortex-xdr-update-incident
    description: "Update an incident's status, severity, assignment and resolve comment (write-back / close the loop)."
    inputs_schema:
      properties:
        incident_id: { type: string, description: "Incident ID to update" }
        status: { type: string, description: "New status (new, under_investigation, resolved_threat_handled, resolved_known_issue, resolved_duplicate, resolved_false_positive, resolved_true_positive, resolved_security_testing, resolved_auto)" }
        manual_severity: { type: string, description: "Override severity (low, medium, high, critical)" }
        assigned_user_mail: { type: string, description: "Assignee email" }
        assigned_user_pretty_name: { type: string, description: "Assignee display name" }
        unassign: { type: boolean, description: "Clear the assignment when true" }
        resolve_comment: { type: string, description: "Resolution comment (shown when resolving)" }
      required: [incident_id]
    outputs_schema: { properties: {} }
  - id: get_alerts
    name: cortex-xdr-get-alerts
    description: "Retrieve alerts using a custom filter (get_alerts_by_filter_data). Returns rich alert objects."
    risk: read
    inputs_schema:
      properties:
        severity: { type: string, description: "Comma-separated severities (low, medium, high, critical)" }
        created_after: { type: string, description: "Lower bound on alert source_insert_ts, epoch ms" }
        limit: { type: number, description: "Maximum alerts to fetch (default 100)" }
      required: []
    outputs_schema: { properties: {} }
  - id: insert_parsed_alerts
    name: cortex-xdr-insert-parsed-alerts
    description: "Push external alerts (parsed JSON objects) into Cortex XDR for correlation."
    inputs_schema:
      properties:
        alerts: { type: string, description: "JSON array of parsed alert objects (each with product, vendor, severity, alert_name, etc.)" }
      required: [alerts]
    outputs_schema: { properties: {} }
  - id: insert_cef_alerts
    name: cortex-xdr-insert-cef-alerts
    description: "Push external alerts in CEF format into Cortex XDR for correlation."
    inputs_schema:
      properties:
        alerts: { type: string, description: "CEF alert lines: a JSON array of CEF strings, or newline-separated CEF lines" }
      required: [alerts]
    outputs_schema: { properties: {} }

  # ── Endpoints ─────────────────────────────────────────────────────────────
  - id: get_endpoints
    name: cortex-xdr-get-endpoints
    description: "List/search endpoints by hostname, IP, status, platform, group, etc."
    risk: read
    inputs_schema:
      properties:
        hostname: { type: string, description: "Hostname to filter by" }
        ip_list: { type: string, description: "Comma-separated IPs" }
        status: { type: string, description: "Endpoint status (connected, disconnected, ...)" }
        platform: { type: string, description: "OS platform (windows, linux, macos, android)" }
        limit: { type: number, description: "Max endpoints (default 30)" }
      required: []
    outputs_schema: { properties: {} }
  - id: isolate_endpoint
    name: cortex-xdr-isolate-endpoint
    description: "Network-isolate an endpoint by endpoint (agent) ID."
    inputs_schema:
      properties:
        endpoint_id: { type: string, description: "Endpoint (agent) ID to isolate" }
        incident_id: { type: string, description: "Optional incident ID to associate the action with" }
      required: [endpoint_id]
    outputs_schema: { properties: {} }
  - id: unisolate_endpoint
    name: cortex-xdr-unisolate-endpoint
    description: "Remove network isolation from an endpoint by endpoint (agent) ID."
    inputs_schema:
      properties:
        endpoint_id: { type: string, description: "Endpoint (agent) ID to unisolate" }
        incident_id: { type: string, description: "Optional incident ID to associate the action with" }
      required: [endpoint_id]
    outputs_schema: { properties: {} }
  - id: scan_endpoints
    name: cortex-xdr-scan-endpoints
    description: "Trigger a malware scan on endpoints matching the given filters (or all)."
    inputs_schema:
      properties:
        endpoint_id_list: { type: string, description: "Comma-separated endpoint IDs (omit + use all=true to scan all)" }
        hostname: { type: string, description: "Comma-separated hostnames" }
        all: { type: boolean, description: "Scan all endpoints when true and no other filter is set" }
        incident_id: { type: string, description: "Optional incident ID" }
      required: []
    outputs_schema: { properties: {} }
  - id: get_policy
    name: cortex-xdr-get-policy
    description: "Get the policy name applied to an endpoint."
    risk: read
    inputs_schema:
      properties:
        endpoint_id: { type: string, description: "Endpoint (agent) ID" }
      required: [endpoint_id]
    outputs_schema: { properties: {} }

  # ── Hash block / allow lists ──────────────────────────────────────────────
  - id: blocklist_files
    name: cortex-xdr-blocklist-files
    description: "Add file hashes to the block list."
    inputs_schema:
      properties:
        hash_list: { type: string, description: "Comma-separated SHA-256 hashes to block" }
        comment: { type: string, description: "Optional comment" }
        incident_id: { type: string, description: "Optional incident ID" }
      required: [hash_list]
    outputs_schema: { properties: {} }
  - id: remove_blocklist_files
    name: cortex-xdr-remove-blocklist-files
    description: "Remove file hashes from the block list."
    inputs_schema:
      properties:
        hash_list: { type: string, description: "Comma-separated SHA-256 hashes to remove" }
        comment: { type: string, description: "Optional comment" }
        incident_id: { type: string, description: "Optional incident ID" }
      required: [hash_list]
    outputs_schema: { properties: {} }
  - id: allowlist_files
    name: cortex-xdr-allowlist-files
    description: "Add file hashes to the allow list."
    inputs_schema:
      properties:
        hash_list: { type: string, description: "Comma-separated SHA-256 hashes to allow" }
        comment: { type: string, description: "Optional comment" }
        incident_id: { type: string, description: "Optional incident ID" }
      required: [hash_list]
    outputs_schema: { properties: {} }
  - id: remove_allowlist_files
    name: cortex-xdr-remove-allowlist-files
    description: "Remove file hashes from the allow list."
    inputs_schema:
      properties:
        hash_list: { type: string, description: "Comma-separated SHA-256 hashes to remove" }
        comment: { type: string, description: "Optional comment" }
        incident_id: { type: string, description: "Optional incident ID" }
      required: [hash_list]
    outputs_schema: { properties: {} }

  # ── File quarantine / restore ─────────────────────────────────────────────
  - id: quarantine_files
    name: cortex-xdr-quarantine-files
    description: "Quarantine a file by path + hash on the given endpoints."
    inputs_schema:
      properties:
        endpoint_id_list: { type: string, description: "Comma-separated endpoint IDs" }
        file_path: { type: string, description: "Full path of the file to quarantine" }
        file_hash: { type: string, description: "SHA-256 of the file" }
        incident_id: { type: string, description: "Optional incident ID" }
      required: [endpoint_id_list, file_path, file_hash]
    outputs_schema: { properties: {} }
  - id: restore_file
    name: cortex-xdr-restore-file
    description: "Restore a quarantined file by hash."
    inputs_schema:
      properties:
        file_hash: { type: string, description: "SHA-256 of the file to restore" }
        endpoint_id: { type: string, description: "Optional endpoint ID" }
        incident_id: { type: string, description: "Optional incident ID" }
      required: [file_hash]
    outputs_schema: { properties: {} }
  - id: get_quarantine_status
    name: cortex-xdr-get-quarantine-status
    description: "Check whether a file is quarantined on an endpoint."
    risk: read
    inputs_schema:
      properties:
        endpoint_id: { type: string, description: "Endpoint ID" }
        file_path: { type: string, description: "File path" }
        file_hash: { type: string, description: "SHA-256 of the file" }
      required: [endpoint_id, file_path, file_hash]
    outputs_schema: { properties: {} }

  # ── Real-time scripts ─────────────────────────────────────────────────────
  - id: run_script
    name: cortex-xdr-run-script
    description: "Run a script (by UID) on endpoints with optional parameters."
    inputs_schema:
      properties:
        script_uid: { type: string, description: "Script UID" }
        endpoint_ids: { type: string, description: "Comma-separated endpoint IDs" }
        parameters: { type: string, description: "JSON object of parameter values" }
        timeout: { type: number, description: "Timeout in seconds (default 600)" }
        incident_id: { type: string, description: "Optional incident ID" }
      required: [script_uid, endpoint_ids]
    outputs_schema: { properties: {} }
  - id: get_script_execution_results
    name: cortex-xdr-get-script-execution-results
    description: "Get the results of a script execution by action ID."
    risk: read
    inputs_schema:
      properties:
        action_id: { type: string, description: "Action ID returned by run_script" }
      required: [action_id]
    outputs_schema: { properties: {} }
  - id: get_scripts
    name: cortex-xdr-get-scripts
    description: "List available scripts, optionally filtered by name/description/OS support."
    risk: read
    inputs_schema:
      properties:
        name: { type: string, description: "Comma-separated script names" }
        windows_supported: { type: boolean, description: "Filter scripts supporting Windows" }
      required: []
    outputs_schema: { properties: {} }

  # ── Actions / misc ────────────────────────────────────────────────────────
  - id: action_status
    name: cortex-xdr-action-status
    description: "Get the status of a group action by action ID."
    risk: read
    inputs_schema:
      properties:
        action_id: { type: string, description: "Group action ID" }
      required: [action_id]
    outputs_schema: { properties: {} }
  - id: get_distribution_versions
    name: cortex-xdr-get-distribution-versions
    description: "List available agent installer versions."
    risk: read
    inputs_schema:
      properties: {}
      required: []
    outputs_schema: { properties: {} }

  - id: delete_endpoints
    name: cortex-xdr-delete-endpoints
    description: "Delete endpoints (agents) by ID."
    inputs_schema:
      properties:
        endpoint_ids: { type: string, description: "Comma-separated endpoint IDs to delete" }
      required: [endpoint_ids]
    outputs_schema: { properties: {} }
  - id: set_endpoint_alias
    name: cortex-xdr-set-endpoint-alias
    description: "Set the alias name on endpoints."
    inputs_schema:
      properties:
        endpoint_ids: { type: string, description: "Comma-separated endpoint IDs" }
        alias: { type: string, description: "New alias name (empty to clear)" }
      required: [endpoint_ids]
    outputs_schema: { properties: {} }
  - id: abort_scan
    name: cortex-xdr-abort-scan
    description: "Abort a running malware scan on endpoints matching the filters (or all)."
    inputs_schema:
      properties:
        endpoint_id_list: { type: string, description: "Comma-separated endpoint IDs (omit to abort all)" }
        incident_id: { type: string, description: "Optional incident ID" }
      required: []
    outputs_schema: { properties: {} }
  - id: get_original_alerts
    name: cortex-xdr-get-original-alerts
    description: "Get the original raw alert events by alert ID."
    risk: read
    inputs_schema:
      properties:
        alert_id_list: { type: string, description: "Comma-separated alert IDs" }
      required: [alert_id_list]
    outputs_schema: { properties: {} }
  - id: get_script_metadata
    name: cortex-xdr-get-script-metadata
    description: "Get metadata for a script by UID."
    risk: read
    inputs_schema:
      properties:
        script_uid: { type: string, description: "Script UID" }
      required: [script_uid]
    outputs_schema: { properties: {} }
  - id: get_script_code
    name: cortex-xdr-get-script-code
    description: "Get the source code of a script by UID."
    risk: read
    inputs_schema:
      properties:
        script_uid: { type: string, description: "Script UID" }
      required: [script_uid]
    outputs_schema: { properties: {} }
  - id: run_snippet_code_script
    name: cortex-xdr-run-snippet-code-script
    description: "Run an arbitrary code snippet on endpoints."
    inputs_schema:
      properties:
        snippet_code: { type: string, description: "Code snippet to run" }
        endpoint_ids: { type: string, description: "Comma-separated endpoint IDs" }
        incident_id: { type: string, description: "Optional incident ID" }
      required: [snippet_code, endpoint_ids]
    outputs_schema: { properties: {} }
  - id: get_script_execution_status
    name: cortex-xdr-get-script-execution-status
    description: "Get the status of a script execution by action ID."
    risk: read
    inputs_schema:
      properties:
        action_id: { type: string, description: "Action ID" }
      required: [action_id]
    outputs_schema: { properties: {} }
  - id: retrieve_file
    name: cortex-xdr-retrieve-file
    description: "Retrieve files from endpoints by OS-specific path lists."
    inputs_schema:
      properties:
        endpoint_ids: { type: string, description: "Comma-separated endpoint IDs" }
        windows: { type: string, description: "Comma-separated Windows file paths" }
        linux: { type: string, description: "Comma-separated Linux file paths" }
        macos: { type: string, description: "Comma-separated macOS file paths" }
        incident_id: { type: string, description: "Optional incident ID" }
      required: [endpoint_ids]
    outputs_schema: { properties: {} }
  - id: retrieve_file_details
    name: cortex-xdr-retrieve-file-details
    description: "Get the download details of a file-retrieval action."
    risk: read
    inputs_schema:
      properties:
        action_id: { type: string, description: "Group action ID from retrieve_file" }
      required: [action_id]
    outputs_schema: { properties: {} }
  - id: add_exclusion
    name: cortex-xdr-add-exclusion
    description: "Add an alert exclusion."
    inputs_schema:
      properties:
        name: { type: string, description: "Exclusion name" }
        indicator: { type: string, description: "JSON indicator object for the exclusion filter" }
        status: { type: string, description: "ENABLED or DISABLED (default ENABLED)" }
      required: [name, indicator]
    outputs_schema: { properties: {} }
  - id: delete_exclusion
    name: cortex-xdr-delete-exclusion
    description: "Delete an alert exclusion by ID."
    inputs_schema:
      properties:
        alert_exclusion_id: { type: number, description: "Exclusion ID" }
      required: [alert_exclusion_id]
    outputs_schema: { properties: {} }
  - id: get_exclusion
    name: cortex-xdr-get-exclusion
    description: "List alert exclusions."
    risk: read
    inputs_schema:
      properties:
        tenant_id: { type: string, description: "Optional tenant ID" }
      required: []
    outputs_schema: { properties: {} }
  - id: add_tag_endpoint
    name: cortex-xdr-add-tag-endpoint
    description: "Add a tag to endpoints."
    inputs_schema:
      properties:
        endpoint_ids: { type: string, description: "Comma-separated endpoint IDs" }
        tag: { type: string, description: "Tag to add" }
      required: [endpoint_ids, tag]
    outputs_schema: { properties: {} }
  - id: remove_tag_endpoint
    name: cortex-xdr-remove-tag-endpoint
    description: "Remove a tag from endpoints."
    inputs_schema:
      properties:
        endpoint_ids: { type: string, description: "Comma-separated endpoint IDs" }
        tag: { type: string, description: "Tag to remove" }
      required: [endpoint_ids, tag]
    outputs_schema: { properties: {} }
  - id: get_device_control_violations
    name: cortex-xdr-get-device-control-violations
    description: "List device control (USB) violations."
    risk: read
    inputs_schema:
      properties:
        endpoint_ids: { type: string, description: "Comma-separated endpoint IDs" }
        type: { type: string, description: "Comma-separated violation types" }
        timestamp_gte: { type: string, description: "Lower bound timestamp (ISO8601 or epoch ms)" }
      required: []
    outputs_schema: { properties: {} }
  - id: list_users
    name: cortex-xdr-list-users
    description: "List Cortex XDR users."
    risk: read
    inputs_schema:
      properties: {}
      required: []
    outputs_schema: { properties: {} }
  - id: get_risk_score
    name: cortex-xdr-get-risk-score
    description: "Get the risk score of a user or host by ID."
    risk: read
    inputs_schema:
      properties:
        id: { type: string, description: "User or host identifier" }
      required: [id]
    outputs_schema: { properties: {} }
  - id: list_risky_users
    name: cortex-xdr-list-risky-users
    description: "List risky users."
    risk: read
    inputs_schema:
      properties: {}
      required: []
    outputs_schema: { properties: {} }
  - id: list_risky_hosts
    name: cortex-xdr-list-risky-hosts
    description: "List risky hosts."
    risk: read
    inputs_schema:
      properties: {}
      required: []
    outputs_schema: { properties: {} }
  - id: list_user_groups
    name: cortex-xdr-list-user-groups
    description: "Get user groups by name."
    risk: read
    inputs_schema:
      properties:
        group_names: { type: string, description: "Comma-separated group names" }
      required: []
    outputs_schema: { properties: {} }
  - id: list_roles
    name: cortex-xdr-list-roles
    description: "Get roles by name."
    risk: read
    inputs_schema:
      properties:
        role_names: { type: string, description: "Comma-separated role names" }
      required: []
    outputs_schema: { properties: {} }
  - id: set_user_role
    name: cortex-xdr-set-user-role
    description: "Assign a role to users."
    inputs_schema:
      properties:
        user_emails: { type: string, description: "Comma-separated user emails" }
        role_name: { type: string, description: "Role name to assign" }
      required: [user_emails, role_name]
    outputs_schema: { properties: {} }
  - id: remove_user_role
    name: cortex-xdr-remove-user-role
    description: "Remove the role assignment from users."
    inputs_schema:
      properties:
        user_emails: { type: string, description: "Comma-separated user emails" }
      required: [user_emails]
    outputs_schema: { properties: {} }
  - id: audit_management_logs
    name: cortex-xdr-audit-management-logs
    description: "Retrieve management audit logs."
    risk: read
    inputs_schema:
      properties:
        email: { type: string, description: "Comma-separated emails" }
        type: { type: string, description: "Comma-separated log types" }
        timestamp_gte: { type: string, description: "Lower bound timestamp (ISO8601 or epoch ms)" }
        limit: { type: number, description: "Max records (default 100)" }
      required: []
    outputs_schema: { properties: {} }
  - id: get_audit_agent_reports
    name: cortex-xdr-get-audit-agent-reports
    description: "Retrieve agent audit reports."
    risk: read
    inputs_schema:
      properties:
        endpoint_ids: { type: string, description: "Comma-separated endpoint IDs" }
        type: { type: string, description: "Comma-separated report types" }
        timestamp_gte: { type: string, description: "Lower bound timestamp (ISO8601 or epoch ms)" }
        limit: { type: number, description: "Max records (default 100)" }
      required: []
    outputs_schema: { properties: {} }
  - id: get_distribution_url
    name: cortex-xdr-get-distribution-url
    description: "Get the download URL of an agent installer distribution."
    risk: read
    inputs_schema:
      properties:
        distribution_id: { type: string, description: "Distribution ID" }
        package_type: { type: string, description: "Package type (sh, rpm, deb, pkg, x86, x64, ...)" }
      required: [distribution_id, package_type]
    outputs_schema: { properties: {} }
  - id: get_distribution_status
    name: cortex-xdr-get-distribution-status
    description: "Get the build status of an agent installer distribution."
    risk: read
    inputs_schema:
      properties:
        distribution_id: { type: string, description: "Distribution ID" }
      required: [distribution_id]
    outputs_schema: { properties: {} }
  - id: create_distribution
    name: cortex-xdr-create-distribution
    description: "Create an agent installer distribution."
    inputs_schema:
      properties:
        name: { type: string, description: "Distribution name" }
        platform: { type: string, description: "Platform (windows, linux, macos, android)" }
        package_type: { type: string, description: "standalone or upgrade (default standalone)" }
        agent_version: { type: string, description: "Agent version" }
        description: { type: string, description: "Optional description" }
      required: [name, platform]
    outputs_schema: { properties: {} }

  - id: test_connection
    name: cortex-xdr-test-connection
    description: "Verify connectivity and credentials (used by the Test button)."
    risk: read
    inputs_schema:
      properties: {}
      required: []
    outputs_schema: { properties: {} }

ingestion:
  command: get_incidents
  mapper: get_incidents
  default_incident_type: "Cortex XDR Incident"
