Workflow and runner visibility
-
Workflow runner matching: Adds
GH_RunsOnto associate workflow jobs with eligible self-hosted runners using statically defined group and label selectors. Dynamic selectors are identified but not resolved, and matches are suppressed when Actions is disabled. -
Effective workflow permissions: Calculates
effective_github_token_permissionsusing repository defaults and workflow- and job-level overrides. Permissions are represented in query-friendly scope:access form. -
Runner job interception: Adds traversable
GH_CanInterceptJobrelationships for persistent self-hosted runners capable of intercepting workflow jobs.GH_CanAccessSecretidentifies repository, organization, and environment secrets available to a job’s execution context. New saved searches highlight interceptable jobs and exposed credentials. -
Environment OIDC capability: Adds traversable
GH_CanRequestOIDCTokenForrelationships when a job deploys to an environment with effectiveid-token:writepermission. This models the capability to request a token, not observed token issuance or its final claims.
Credentials and access
-
Normalized credential permissions: App installation, fine-grained PAT, PAT request, and workflow permission properties now use arrays of
scope:accessvalues rather than JSON strings. PAT requests now include requested organization and repository permissions. -
Repository deploy keys: Adds
GH_DeployKeynodes with repository containment/access and, where available,GH_AddedDeployKeyattribution. Captures key status, public key material, read-only/read-write access, and last-use metadata.
Collection and identity improvements
-
Deployment detection: Detects GitHub.com versus GitHub Enterprise Server at startup.
Records
github_deployment_typeand, for GHES,ghes_versionon collected organization and enterprise nodes. -
Environment collection performance: Uses GraphQL counts to avoid environment REST requests for repositories with no environments.
Repository nodes now report
branch_countandenvironment_count. -
Organization role naming: Qualifies organization role names as organization/role to prevent ambiguity across organizations while retaining the unqualified value in
short_name. Node IDs remain unchanged. -
Immutable GitHub database IDs: Persists numeric organization, repository, and repository-owner database IDs needed to correlate immutable GitHub OIDC subjects.
This will solve the issue with newer
GH_CanAssumeIdentityedges. - Source-family labels: Assigns GitHub, SAML, or SCIM kinds according to node family. Improves source filtering and prevents SCIM objects from being presented as native GitHub nodes.
Shared trusted SAML issuers
Trusted inboundSAML_Issuer nodes are now identified by their byte-exact SAML entity ID and collecting Okta tenant, rather than by the individual Okta Identity Provider that referenced them.-
Multiple identity providers in one tenant that trust the same entity now converge on one
SAML_Issuer. - Identical entity IDs in different Okta tenants remain isolated.
-
Each
Okta_IdentityProvider,SAML_ServiceProvider, andSAML_TrustsIssuerrelationship remains distinct, preserving trust provenance. - Per-IdP ownership properties were removed from the shared issuer node.
- Missing or empty issuer values are rejected, and tenant URLs are normalized and validated.
Upgrade noticeIssuer IDs changed. Existing IdP-keyed issuer nodes and trust edges will age out according to BloodHound retention; purge the graph before testing if an immediately clean result is required.
Per-node source kinds
Graph output now distinguishes native Okta nodes from normalized SAML nodes using per-node source kinds.-
Native nodes, including
Okta_IdentityProvider, receive the Okta kind. -
Normalized
SAML_*nodes receive the SAML kind. - The previous graph-wide source-kind assignment was removed.
-
openhound>=0.4.0is now a runtime dependency.
Optional collection performance telemetry
Added disabled-by-default performance telemetry for diagnosing and tuning Okta collections.- Records bounded JSONL diagnostics for endpoint latency, HTTP outcomes, retries, quota observations, concurrency, pacing, pagination, and row counts.
- Separates HTTP execution, concurrency-slot waits, proactive pacing, and retry backoff.
- Records effective DLT extraction and Okta performance settings.
- Uses normalized endpoints and excludes credentials, tenant hostnames, URLs, cursors, object identifiers, response bodies, and exception text.
- Telemetry uses no additional Okta requests or permissions and does not alter collection scope or scheduling.
- Export failures are isolated from collection behavior; interrupted or incomplete runs retain available progress records.
- Memory, queue, interval, and file-size limits bound telemetry overhead.