-
Notifications
You must be signed in to change notification settings - Fork 836
Add Huntress.io integration #3019
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
kyletaylored
wants to merge
44
commits into
DataDog:master
Choose a base branch
from
kyletaylored:huntress
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 30 commits
Commits
Show all changes
44 commits
Select commit
Hold shift + click to select a range
acfcd29
Add Huntress.io integration
kyletaylored d29312f
Update codeowners for huntress
kyletaylored 04bf61c
Fix ddev formatting issues
kyletaylored f054ec8
Fix changelog formatting
kyletaylored d52a491
Remove media, use unclaimed source id
kyletaylored 9f0f722
Fix validation issues
kyletaylored c1b2128
Add multiple log query support per API key
kyletaylored 785969d
Run formatter
kyletaylored ba274ff
Already moved mock data file
kyletaylored 9cfceb8
Add query_name, remove md5, fix monitors
kyletaylored a9ec4af
Add escape hatch for hitting rate limit
kyletaylored f1c4d69
Fix monitor schema
kyletaylored c31b9e0
Merge branch 'master' into huntress
kyletaylored 5d97e9d
Fix ascii validation
kyletaylored 157d3d6
Drop secret from hash
kyletaylored accc689
Use non-secret stable discriminator not derived from keys
kyletaylored 27671cf
Apply linting
kyletaylored 57b2113
Update codecov (add huntress)
kyletaylored a92e10d
Add Huntress to test-all.yml
kyletaylored c31bf35
Add missing spec item
kyletaylored 27956f1
Merge branch 'master' into huntress
kyletaylored 9c1c205
Remove old conf artifact
kyletaylored 752339c
Apply suggestions from code review
kyletaylored 26f4835
Move validation to dedicated section
kyletaylored e41ae65
Replace "Data Collected" section with recommendation
kyletaylored 13b35ee
Fix metadata column issue (suggestion added a comma that broke valida…
kyletaylored a4d6820
Remove en dash as validation rejects it as a non-ascii character
kyletaylored 0085008
Fix config default value
kyletaylored 3ac80f3
Fix config validation issue
kyletaylored 820fb75
Merge branch 'master' into huntress
kyletaylored 31bf819
Apply suggestions from code review
kyletaylored 1d44e32
Update README with recommendations:
kyletaylored 29045e1
Fix timestamp parsing, 429 retry loop, and org tag lookup; add run su…
kyletaylored 29771cd
Update timestamp parsing
kyletaylored e98e03c
Update log format
kyletaylored 739534e
Add log batching fallback and log declaration
kyletaylored 982c08a
Apply suggestions from code review
kyletaylored 7511713
Reorder readme sections
kyletaylored 49381e0
Add esql name as log tag
kyletaylored 933d83d
Fix missing reference
kyletaylored ad8d214
Fix linting error
kyletaylored eb133bb
Add last missing reference
kyletaylored 0e50bc7
Merge branch 'master' into huntress
kyletaylored 6a29a08
Apply suggestions from code review
domalessi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # CHANGELOG - Huntress | ||
|
|
||
| ## Unreleased | ||
|
|
||
| ***Added***: | ||
|
|
||
| * Initial release of the Huntress SIEM integration for Datadog. | ||
| * Polls the Huntress Managed SIEM API via ES|QL, enriches logs with organization metadata, and forwards all events to Datadog Logs. | ||
| * Emits collection health metrics and a pre-built overview dashboard with monitor templates. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,199 @@ | ||
| # Huntress | ||
|
|
||
| ## Overview | ||
|
|
||
| [Huntress](https://www.huntress.com/) is a managed security platform providing endpoint detection and response (EDR), antivirus, security awareness training, and a Managed SIEM product that continuously collects and analyzes endpoint telemetry. | ||
|
|
||
| This integration polls the Huntress Managed SIEM API using ES|QL queries and forwards all security events to Datadog as logs. Each collection run: | ||
|
kyletaylored marked this conversation as resolved.
Outdated
|
||
|
|
||
| 1. Loads a checkpoint (the timestamp of the last successful collection) | ||
| 2. Executes a configurable ES|QL query for the elapsed time window | ||
| 3. Paginates through all result pages | ||
| 4. Optionally enriches each log with Huntress organization metadata (org name, key, account ID) | ||
| 5. Forwards logs to Datadog preserving all Elastic Common Schema (ECS) field names | ||
| 6. Advances the checkpoint only after all pages are successfully sent | ||
|
|
||
| This integration is designed for managed security providers (MSPs) and enterprise teams who want to correlate Huntress threat detections alongside infrastructure and application telemetry in Datadog. | ||
|
|
||
| ## Setup | ||
|
|
||
| ### Prerequisites | ||
|
|
||
| - Datadog Agent 7.x or later | ||
| - A Huntress account with the Managed SIEM feature enabled | ||
| - Huntress API credentials (public API key + secret key) from the Huntress Partner Portal under **Settings > API Credentials** | ||
|
kyletaylored marked this conversation as resolved.
Outdated
|
||
|
|
||
| ### Installation | ||
|
|
||
| Install the integration package from the Agent: | ||
|
|
||
| ```bash | ||
| datadog-agent integration install -t datadog-huntress==1.0.0 | ||
| ``` | ||
|
|
||
| ### Configuration | ||
|
|
||
| 1. Create the configuration file at `/etc/datadog-agent/conf.d/huntress.yaml` (Linux/macOS) or `C:\ProgramData\Datadog\conf.d\huntress.yaml` (Windows). A fully-annotated example is at `datadog_checks/huntress/data/conf.yaml.example`. | ||
|
kyletaylored marked this conversation as resolved.
Outdated
|
||
|
|
||
| 2. Edit `huntress.yaml` with your credentials: | ||
|
|
||
| ```yaml | ||
| init_config: {} | ||
|
|
||
| instances: | ||
| - huntress_api_key: "<your_public_api_key>" | ||
| huntress_secret_key: "<your_secret_api_key>" | ||
| log_queries: | ||
| - name: "all-logs" | ||
| esql_query: "FROM logs" | ||
| tags: | ||
| - "source:huntress" | ||
| - "service:huntress-siem" | ||
| - "env:production" | ||
| ``` | ||
|
|
||
| 3. Restart the Agent: | ||
|
|
||
| ```bash | ||
| # Linux (systemd) | ||
| sudo systemctl restart datadog-agent | ||
|
|
||
| # macOS | ||
| sudo launchctl stop com.datadoghq.agent && sudo launchctl start com.datadoghq.agent | ||
| ``` | ||
|
|
||
| ### Validation | ||
|
|
||
| Run the Agent status command and look for `huntress` under the **Checks** section: | ||
|
kyletaylored marked this conversation as resolved.
Outdated
|
||
|
|
||
| ```bash | ||
| sudo datadog-agent check huntress | ||
| ``` | ||
|
|
||
| Logs appear in Datadog Log Explorer filtered by `source:huntress` within one collection interval (default: 15 minutes). | ||
|
kyletaylored marked this conversation as resolved.
Outdated
|
||
|
|
||
| ### Multiple Huntress accounts | ||
|
kyletaylored marked this conversation as resolved.
Outdated
|
||
|
|
||
| Add additional blocks under `instances:`. Each block runs independently with its own checkpoint, org metadata cache, and metrics: | ||
|
|
||
| ```yaml | ||
| instances: | ||
| - huntress_api_key: "<account1_key>" | ||
| huntress_secret_key: "<account1_secret>" | ||
| log_queries: | ||
| - name: "all-logs" | ||
| esql_query: "FROM logs" | ||
| tags: ["source:huntress", "env:production"] | ||
|
|
||
| - huntress_api_key: "<account2_key>" | ||
| huntress_secret_key: "<account2_secret>" | ||
| log_queries: | ||
| - name: "all-logs" | ||
| esql_query: "FROM logs" | ||
| tags: ["source:huntress", "env:staging"] | ||
| ``` | ||
|
|
||
| ### Configuration reference | ||
|
|
||
| **`init_config` options** (apply to all instances): | ||
|
|
||
| | Field | Required | Default | Description | | ||
| | ----------------- | -------- | ------- | ------------------------------------------------- | | ||
| | `request_timeout` | No | `30` | HTTP request timeout in seconds for all API calls | | ||
|
|
||
| **`instances` options** (per Huntress account): | ||
|
|
||
| | Field | Required | Default | Description | | ||
| | -------------------------- | -------- | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| | `huntress_api_key` | Yes | - | Huntress public API key | | ||
| | `huntress_secret_key` | Yes | - | Huntress secret API key | | ||
| | `log_queries` | No\* | - | List of query objects; each has `name` (required), `esql_query` (required, must begin with `FROM logs`), and `tags` (optional). `name` is used as the `query_name` tag on metrics | | ||
| | `metrics.agents.enabled` | No\* | `false` | Collect agent fleet metrics (total, by platform, by Defender/firewall status) | | ||
| | `metrics.agents.max_pages` | No | `20` | Max pages of agents to fetch per run (500 agents/page) | | ||
| | `enrich_with_org_tags` | No | `true` | Fetch and attach org metadata as log tags | | ||
| | `org_cache_ttl_seconds` | No | `3600` | How long to cache org metadata (seconds) | | ||
| | `max_pages_per_run` | No | `100` | Page cap per query per run (~20,000 logs maximum) | | ||
| | `huntress_base_url` | No | `https://api.huntress.io` | Override for sandbox environments | | ||
| | `tags` | No | `[]` | Extra tags on every forwarded metric and log | | ||
|
|
||
| \* At least one of `log_queries` or `metrics.agents.enabled: true` must be configured per instance. | ||
|
kyletaylored marked this conversation as resolved.
Outdated
|
||
|
|
||
| ### Rate limit considerations | ||
|
kyletaylored marked this conversation as resolved.
Outdated
|
||
|
|
||
| The Huntress API allows 60 requests per minute per API key pair. A typical run with 3 SIEM queries and agent metrics uses roughly 5 to 25 requests, well within this budget. For large accounts with high log volume or thousands of agents, consider splitting concerns across two instances using separate API key pairs: | ||
|
domalessi marked this conversation as resolved.
Outdated
|
||
|
|
||
| ```yaml | ||
| instances: | ||
| # Instance 1: SIEM log collection only | ||
| - huntress_api_key: "<logs-key>" | ||
| huntress_secret_key: "<logs-secret>" | ||
| log_queries: | ||
| - name: "all-logs" | ||
| esql_query: "FROM logs" | ||
|
|
||
| # Instance 2: agent metrics only (isolated rate limit budget) | ||
| - huntress_api_key: "<metrics-key>" | ||
| huntress_secret_key: "<metrics-secret>" | ||
| metrics: | ||
| agents: | ||
| enabled: true | ||
| ``` | ||
|
|
||
| ## Data Collected | ||
|
kyletaylored marked this conversation as resolved.
|
||
|
|
||
| ### Logs | ||
|
|
||
| All logs collected from the Huntress Managed SIEM API are forwarded to Datadog with: | ||
|
|
||
| - `ddsource: huntress`: enables automatic log pipeline processing | ||
|
kyletaylored marked this conversation as resolved.
Outdated
|
||
| - ECS field names preserved as top-level log attributes (for example, `event.category`, `host.hostname`, `user.name`) | ||
| - Organization metadata tags when `enrich_with_org_tags: true` (for example, `huntress_org_name`, `huntress_org_key`, `huntress_account_id`) | ||
|
|
||
| ### Metrics | ||
|
|
||
| See [metadata.csv][1] for a list of metrics provided by this integration. | ||
|
|
||
| ### Events | ||
|
|
||
| The Huntress integration does not include any events. | ||
|
|
||
| ### Service Checks | ||
|
|
||
| See [service_checks.json][2] for a list of service checks provided by this integration. | ||
|
kyletaylored marked this conversation as resolved.
Outdated
|
||
|
|
||
| ## Troubleshooting | ||
|
|
||
| **No logs in Datadog after first run** | ||
|
|
||
| - Run `sudo datadog-agent check huntress` and inspect the output | ||
| - Verify the API key pair is valid by checking the Huntress Partner Portal | ||
| - Confirm the Managed SIEM feature is enabled on the account | ||
| - Check that each `log_queries[].esql_query` begins with `FROM logs` | ||
|
|
||
| **`huntress.siem.errors` count is increasing** | ||
|
|
||
| Inspect the `error_type` tag to identify the root cause: | ||
|
|
||
| | `error_type` | Cause | Resolution | | ||
| | ------------------ | ---------------------------------- | ------------------------------------------------------------- | | ||
| | `auth_failure` | Invalid or rotated API credentials | Update `huntress_api_key` / `huntress_secret_key` | | ||
|
kyletaylored marked this conversation as resolved.
Outdated
|
||
| | `timeout` | ES\|QL query too broad | Add a `KEEP` or `WHERE` clause to the query | | ||
|
domalessi marked this conversation as resolved.
Outdated
|
||
| | `invalid_query` | Malformed ES\|QL | Fix the `esql_query` value in the failing `log_queries` entry | | ||
|
domalessi marked this conversation as resolved.
Outdated
|
||
| | `server_error` | Transient Huntress API error | Check [Huntress status page](https://status.huntress.com) | | ||
|
kyletaylored marked this conversation as resolved.
Outdated
|
||
| | `connection_error` | Network issue | Verify connectivity from the Agent host to `api.huntress.io` | | ||
| | `run_failure` | Unexpected error during collection | Check Agent logs for the full stack trace | | ||
|
|
||
| **`huntress.siem.api_call_remaining` is very low or zero** | ||
|
kyletaylored marked this conversation as resolved.
Outdated
|
||
|
|
||
| The Huntress API allows 60 requests per minute. The integration logs a warning when fewer than 10 requests remain in a given minute. If this happens regularly, reduce `max_pages_per_run` or increase `min_collection_interval` to spread out collection runs. | ||
|
|
||
| **Duplicate logs after Agent restart** | ||
|
|
||
| This is expected on the first restart after a failed run. The checkpoint is only advanced after all pages are successfully sent. | ||
|
kyletaylored marked this conversation as resolved.
Outdated
|
||
|
|
||
| ## Support | ||
|
|
||
| For questions and support, [contact Datadog support][2]. | ||
|
|
||
| [1]: https://github.com/DataDog/integrations-extras/blob/master/huntress/metadata.csv | ||
| [2]: https://docs.datadoghq.com/help/ | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,121 @@ | ||
| name: Huntress | ||
| files: | ||
| - name: huntress.yaml | ||
| options: | ||
| - template: init_config | ||
| options: | ||
| - template: init_config/default | ||
| - name: request_timeout | ||
| description: | | ||
| HTTP request timeout in seconds applied to all Huntress API calls. | ||
| Increase this if the Huntress SIEM API is slow to respond on large queries. | ||
| value: | ||
| type: number | ||
| example: 30 | ||
| default: 30 | ||
| - template: instances | ||
| options: | ||
| - template: instances/default | ||
| overrides: | ||
| min_collection_interval.value.default: 900 | ||
| min_collection_interval.value.example: 900 | ||
| - name: huntress_api_key | ||
| required: true | ||
| secret: true | ||
| description: | | ||
| Huntress public API key. Obtain from the Huntress Partner Portal under | ||
| Settings > API Credentials. Each instance uses its own key pair, enabling | ||
| multiple Huntress accounts to feed into the same Datadog organization. | ||
| value: | ||
| type: string | ||
| example: <HUNTRESS_API_KEY> | ||
| - name: huntress_secret_key | ||
| required: true | ||
| secret: true | ||
| description: | | ||
| Huntress private (secret) API key paired with huntress_api_key. | ||
| value: | ||
| type: string | ||
| example: <HUNTRESS_SECRET_KEY> | ||
| - name: log_queries | ||
| description: | | ||
| List of ES|QL queries to execute against the Huntress SIEM API. Each entry | ||
| requires an esql_query string (must begin with "FROM logs", case-insensitive) | ||
| and an optional tags list attached only to logs produced by that query. | ||
| Multiple queries run independently with separate checkpoints, enabling | ||
| targeted collection for different log types within the same account. | ||
| Do not add time range filters — range_start and range_end are managed | ||
| automatically by the check. | ||
| value: | ||
| type: array | ||
| items: | ||
| type: object | ||
| properties: | ||
| - name: name | ||
| type: string | ||
| - name: esql_query | ||
| type: string | ||
| - name: tags | ||
| type: array | ||
| items: | ||
| type: string | ||
| example: | ||
| - name: "all-logs" | ||
| esql_query: "FROM logs" | ||
| tags: | ||
| - "log_type:all" | ||
| - name: enrich_with_org_tags | ||
| description: | | ||
| When true, the check fetches Huntress organization metadata (org name, | ||
| org key, account ID) and attaches it as log tags. The org cache is | ||
| refreshed according to org_cache_ttl_seconds. | ||
| value: | ||
| type: boolean | ||
| example: true | ||
| default: true | ||
| - name: org_cache_ttl_seconds | ||
| description: | | ||
| How long (in seconds) to cache organization metadata before re-fetching | ||
| from the Huntress API. Set to 0 to refresh on every run. | ||
| value: | ||
| type: integer | ||
| example: 3600 | ||
| default: 3600 | ||
| - name: max_pages_per_run | ||
| description: | | ||
| Maximum number of result pages to fetch per query per run. Each page | ||
| contains up to 200 log events. Protects against runaway pagination on | ||
| large backlogs. If this cap is hit, the checkpoint does not advance and | ||
| remaining pages are fetched on the next run. | ||
| value: | ||
| type: integer | ||
| example: 100 | ||
| default: 100 | ||
| - name: huntress_base_url | ||
| description: | | ||
| Huntress API base URL. Override for sandbox or testing environments. | ||
| value: | ||
| type: string | ||
| example: "https://api.huntress.io" | ||
| default: "https://api.huntress.io" | ||
| - name: metrics | ||
| description: | | ||
| Controls which Huntress data is collected as Datadog metrics beyond the | ||
| standard SIEM run metrics. Omit this section to disable additional metric | ||
| collection (logs-only instance). Configure a separate instance with only | ||
| this section and different API credentials to isolate the agent metrics | ||
| API call budget from SIEM log collection. | ||
| value: | ||
| type: object | ||
| properties: | ||
| - name: agents | ||
| type: object | ||
| properties: | ||
| - name: enabled | ||
| type: boolean | ||
| - name: max_pages | ||
| type: integer | ||
| example: | ||
| agents: | ||
| enabled: true | ||
| max_pages: 20 |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.