Skip to main content

A project powered by SpecterOps - Creators of BloodHound

Okta collector for OpenHound

Slack SpecterOps on Reddit Sponsored by SpecterOps

@SpecterOps on Twitter Connect on LinkedIn Connect on Mastodon


About

OpenHound is a standardized framework for building and running OpenGraph collectors and converters. It is built in Python and powered by the Data Load Tool (DLT) library, giving you a consistent workflow to collect, process, and convert data from any source into BloodHound-compatible graphs.

The openhound-okta extension collects Okta resources and transforms these into usable nodes and edges for BloodHound.

For SAML catalog integrations, see the OIN route evidence and resolver contract. The collector prefers explicit deployed routes and otherwise fails closed unless a reviewed catalog resolver has the complete settings it requires.

Trusted SAML issuer identity

Inbound trusted SAML issuer object IDs are scoped by the collecting Okta tenant domain and the issuer's byte-exact entity ID. Multiple inbound identity providers in one Okta tenant that trust the same issuer therefore share one SAML_Issuer node, while identical entity IDs observed in different Okta tenants remain separate. The entity ID remains available as the semantic value for cross-collector correlation.

The shared-issuer ID change is additive in BloodHound. Existing IdP-keyed issuer nodes and trust edges are not removed immediately by an upload; they age out under the instance's normal retention behavior. Operators testing this change may purge their BloodHound instance when a clean graph is needed.

Python Version

Getting Started

Follow the OpenHound docs to get started:

OAuth app authentication behavior

When the collector uses Okta OAuth app credentials, it shares one bearer token across endpoint clients and refreshes that token before it expires. Long-running collections can therefore continue across the Okta access-token lifetime without failing active resource pagination. If a transient proactive refresh fails while the current token is still valid, the collector temporarily keeps using that token and suppresses repeated refresh attempts for a short cooldown. If Okta rejects a bearer token with HTTP 401, the collector retries once for stale, invalid, or unknown token responses while preserving the current token for known non-token authorization failures. Classic SSWS API token authentication remains static.

Rate-limit behavior

The collector coordinates requests by Okta API endpoint family. It limits concurrent requests, observes X-Rate-Limit-Remaining and X-Rate-Limit-Reset on successful responses, and paces later requests before a bucket is exhausted. HTTP 429 responses retry the same request and pagination cursor until a bounded elapsed-time budget is reached. Transport failures and HTTP 5xx responses retain DLT's retry coverage.

Fan-out resources use explicit page sizes where Okta documents safe maxima. Expanded group collection requests 200 rows per page, application-user collection requests 500 rows per page, application-group assignment collection requests 200 rows per page, group-push mapping collection requests 1,000 rows per page, and identity-provider user collection requests 200 rows per page. Application-group assignments are collected from each application's public assignment endpoint and retain Okta's assignment timestamp, priority, and profile field names without publishing assignment profile values to the graph. Rows stream to DLT; an exhausted required request fails the collection so DLT does not publish an incomplete replacement. If the initial expanded group page repeatedly times out, the collector retries that first page with successively halved limits before failing. With the default configuration, that sequence is 200, 100, then 50.

The defaults can be adjusted in .dlt/config.toml under [sources.source.okta]. DLT environment variables may override the same non-secret settings:

Environment variable Default Purpose
SOURCES__SOURCE__OKTA__APPLICATION_USERS_PAGE_SIZE 500 Application users per page, from 1 through 500
SOURCES__SOURCE__OKTA__GROUPS_PAGE_SIZE 200 Expanded groups per page, from 1 through 200
SOURCES__SOURCE__OKTA__APPLICATION_GROUP_ASSIGNMENTS_PAGE_SIZE 200 Application-group assignments per page, from 20 through 200
SOURCES__SOURCE__OKTA__GROUP_PUSH_MAPPINGS_PAGE_SIZE 1000 Group push mappings per page, from 1 through 1,000
SOURCES__SOURCE__OKTA__IDENTITY_PROVIDER_USERS_PAGE_SIZE 200 Identity-provider users per page, from 1 through 200
SOURCES__SOURCE__OKTA__ENDPOINT_CONCURRENCY 2 Maximum simultaneous requests per endpoint family
SOURCES__SOURCE__OKTA__RATE_LIMIT_MAX_ELAPSED_SECONDS 900 Maximum elapsed retry window for an individual 429 request
SOURCES__SOURCE__OKTA__RATE_LIMIT_REMAINING_RESERVE 1 Requests held in reserve when pacing against a rate-limit window

Optional collection performance telemetry

Collection telemetry is disabled by default. When enabled in config.toml, it writes bounded, value-free JSONL diagnostics to a local directory without requiring DEBUG logging, an external service, an additional Okta permission, or an additional request. The same configuration applies to interactive, scheduled, and containerized openhound collect okta invocations.

[sources.source.okta.telemetry]
enabled = true
output_directory = "./telemetry"
reporting_interval_seconds = 60
max_file_bytes = 10485760
max_interval_records = 1440
queue_capacity = 16

Keep output_directory outside the collection raw-data directory. The collector rejects an unsafe nested telemetry location so diagnostics cannot be discovered, converted, or uploaded as Okta collection data. Each collection creates openhound-okta-<opaque-run-id>.jsonl; disabling telemetry creates no artifact.

Environment variables use the equivalent nested DLT names, such as SOURCES__SOURCE__OKTA__TELEMETRY__ENABLED=true and SOURCES__SOURCE__OKTA__TELEMETRY__OUTPUT_DIRECTORY=/diagnostics. Environment values take precedence over config.toml; omitted values use the defaults shown above. Reporting intervals must be positive, max_file_bytes must be at least 65,536, max_interval_records must be at least 1, and queue_capacity must be at least 2.

The artifact separates concurrency-slot waits, proactive pacing, retry backoff, and HTTP execution. HTTP execution includes response-body transfer but not JSON decoding or downstream row conversion. Wait distributions are summed worker samples, not additive wall-clock attribution. Pages and rows are API yield progress and do not mean DLT committed the output. Collector endpoint families are limiter groups, not verified Okta provider buckets. In particular, zero HTTP 429 responses does not prove that quota was unused.

The summary records DLT's effective extract_workers and extract_max_parallel_items values as well as the Okta settings above. Put shared worker tuning under [extract] in the same config.toml, or use [sources.source.okta.extract] when the override is intentionally scoped to this source. The reported values use DLT's source-scoped resolution and include the values from whichever TOML scope wins. Do not use telemetry artifacts from different settings as direct performance pairs.

The first record marks the run incomplete, periodic interval records retain useful progress after interruption, and a normal end adds a concise complete summary. Output truncation, dropped records, and exporter failure are explicit and value-free. A telemetry write failure is logged but never changes request, retry, or collection failure behavior. See docs/collection-performance-telemetry.md for the record contract, interpretation, troubleshooting, representative collection benchmark, and separate recorder microbenchmark.

Release files for openhound-okta 0.7.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for openhound-okta 0.7.1
File Size Uploaded
openhound_okta-0.7.1.tar.gz 3.7 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for openhound-okta 0.7.1
File Interpreter ABI Platform
openhound_okta-0.7.1-py3-none-any.whl Python 3 none any Details

Total release size: 3.8 MB

Release files / openhound_okta-0.7.1.tar.gz

Download URL openhound_okta-0.7.1.tar.gz
Size 3.7 MB
Tags Source
SHA-256 checksum
How to use checksums
7c82a3ab0bc943823d0390ddd52a070c201427c59250ec4fb7d3d94fc1e6edcf
BLAKE2b-256 checksum
How to use checksums
9e8b1ce835d00fb7d6ca1d4c2bb54233f9121be982e1f351d9ff3573f4e9481e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / openhound_okta-0.7.1-py3-none-any.whl

Download URL openhound_okta-0.7.1-py3-none-any.whl
Size 131.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2ebcd1824fde803ef34275c69f1029e1981843fced422abcc6f51548b445dcf9
BLAKE2b-256 checksum
How to use checksums
36f6b1bae480daa0f4a9e18c19759992b653e9ca40806085e2a237e88efc0901
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

0.8.1

2 release files

0.8.0

2 release files

0.7.4

2 release files

0.7.3

2 release files

0.7.2

2 release files

This release

0.7.1 This release

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.8

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page