feat(hunt-io): add support for hunt v3 api while keeping v2 (#7678) - #7679
Open
Marko Marjanović (m4r35) wants to merge 1 commit into
Open
Marko Marjanović (m4r35) wants to merge 1 commit into
Marko Marjanović (m4r35) wants to merge 1 commit into
Conversation
Contributor License Agreement✅ CLA signed 💚 Thank you Marko Marjanović (@m4r35) for signing the Contributor License Agreement! Your pull request can now be reviewed and merged. We appreciate your contribution to Filigran's open source projects! ❤️ This is an automated message from the Filigran CLA Bot. |
Copilot started reviewing on behalf of
Marko Marjanović (m4r35)
September 11, 2026 16:13
View session
Contributor
There was a problem hiding this comment.
Pull request overview
Adds configurable Hunt.io v3 API support while preserving v2 compatibility through version-specific authentication, validation, documentation, and tests.
Changes:
- Adds normalized API version settings and v3 key validation.
- Implements token/Bearer authentication and session refresh handling.
- Updates tests, deployment configuration, documentation, and generated metadata.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Summary |
|---|---|
external-import/hunt-io/tests/tests_connector/test_settings.py |
Adds configuration validation and normalization tests. |
external-import/hunt-io/tests/tests_connector/test_client_api.py |
Tests version-specific authentication and session refresh. |
external-import/hunt-io/tests/conftest.py |
Adds v3 test configuration fixtures. |
external-import/hunt-io/src/external_import_connector/settings.py |
Adds API version configuration and v3 validation. |
external-import/hunt-io/src/external_import_connector/client_api.py |
Selects authentication headers by API version. |
external-import/hunt-io/README.md |
Documents API version selection. |
external-import/hunt-io/docker-compose.yml |
Adds API version deployment configuration. Moderate finding (1 vote): deprecated API-version aliases are not passed through. |
external-import/hunt-io/config.yml.sample |
Adds sample API version configuration. |
external-import/hunt-io/__metadata__/connector_config_schema.json |
Regenerates the configuration schema. Moderate finding (3 votes): the stable schema $id loses the hunt-io connector slug. |
external-import/hunt-io/__metadata__/CONNECTOR_CONFIG_DOC.md |
Updates generated configuration documentation. |
Suppressed comments (1)
external-import/hunt-io/docker-compose.yml:14
- The Compose sample expands only
HUNT_IO_API_VERSION, so a deployment using either deprecatedCONNECTOR_HUNT_UI_API_VERSIONorCONNECTOR_HUNT_IO_API_VERSIONcannot reach the SDK namespace shim: Compose substitutesv2and silently sends the V2tokenscheme even when the deprecated setting isv3. Please include the deprecated variables in the fallback chain (or pass them through) so the advertised backward-compatible aliases work with this deployment path.
- HUNT_IO_API_VERSION=${HUNT_IO_API_VERSION:-v2}
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…Platform#7678) The two Hunt.io C2 feed APIs use mutually exclusive authentication: V2 expects a `token` header, V3 expects `Authorization: Bearer` with an `ak_`-prefixed key. Each returns HTTP 401 when sent the other's header. Add `hunt_io.api_version` (HUNT_IO_API_VERSION) to select between them, defaulting to v2 so existing deployments are unaffected. The response payload is identical between versions, so parsing and STIX conversion are unchanged. - Select the auth header by version in HTTPSessionManager.create_session, passing the version at both construction and post-timeout refresh - Reject a non-`ak_` key at startup when v3 is selected; V3 returns the same opaque 401 for a malformed key as for a missing one - Normalize blank and mixed-case values, so an undefined compose passthrough (`${HUNT_IO_API_VERSION}` -> "") falls back to the default - Document both versions and regenerate __metadata__
Marko Marjanović (m4r35)
force-pushed
the
feat/hunt-io-add-v3-api-support
branch
from
September 11, 2026 16:42
4adfb34 to
2d1c2fe
Compare
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Proposed changes
hunt_io.api_versionsetting (HUNT_IO_API_VERSION, valuesv2/v3, defaultv2) thatselects the authentication scheme for the Hunt.io C2 feed. V2 (
https://api.hunt.io/v1/feeds/c2)authenticates with a
tokenheader; V3 (https://a.hunt.io/feeds/c2) requiresAuthorization: Bearerwith anak_-prefixed key. The two are mutually exclusive — each returnsHTTP 401 when sent the other's header — so
HTTPSessionManager.create_sessionnow sets the headermatching the selected version, at both construction and post-timeout session refresh.
ak_key at startup whenv3is selected. V3 returns an identical, opaque 401 for amissing key, a malformed key, and a wrong-scheme key, so this converts a confusing runtime failure
into a clear configuration error. Deliberately scoped to V3 only, as V2 documents no prefix rule.
passthrough (
- HUNT_IO_API_VERSION=${HUNT_IO_API_VERSION}) resolves to an empty string, whichwould otherwise fail validation instead of falling back to the default.
api_versionandapi_base_urlmust change together), updateconfig.yml.sample, and regenerate__metadata__.missing the
ak_prefix, and blank/whitespace/uppercase normalisation; plus newcreate_sessioncoverage asserting the correct header per version, that the deprecated namespace still forwards the
new setting, and that a post-timeout session refresh retains bearer auth.
Backward compatibility:
api_versiondefaults tov2, which reproduces existing behaviourexactly. Nothing becomes mandatory — the generated schema's
requiredlist is unchanged — and noexisting variable is renamed or removed. The response payload is byte-identical between versions
(gzipped NDJSON, same record fields), so parsing, STIX conversion, and the entity pipeline are
untouched.
Testing: both paths verified end-to-end against the live APIs on OpenCTI
7.260910.0—authentication, feed fetch, conversion, and ingestion of observables, indicators, malware,
infrastructure and relationships, with no errors from the connector, workers, or platform. Switching
between versions was exercised in both directions. Unit tests pass, and
black,isortandflake8are clean for the changed files.
Related issues
Checklist
Further comments
a.hunt.ioandapi.hunt.ioare separate services rather than two paths on one host, which is why asingle credential cannot address both and why the selector is an explicit setting rather than
something inferred from the base URL. Deriving the version from the URL was considered and rejected:
it couples behaviour to a hostname pattern and breaks for staging or custom hostnames.
The new setting is documented as
HUNT_IO_API_VERSION, matching the current prefix convention. Thedeprecated
CONNECTOR_HUNT_UI_*andCONNECTOR_HUNT_IO_*namespaces still resolve it through theexisting SDK shim, and all three spellings appear in the regenerated config schema.