openhound 0.1.1__tar.gz → 0.1.3.dev2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. {openhound-0.1.1 → openhound-0.1.3.dev2}/.github/workflows/build-and-sign-container.yml +4 -4
  2. {openhound-0.1.1 → openhound-0.1.3.dev2}/PKG-INFO +1 -1
  3. {openhound-0.1.1 → openhound-0.1.3.dev2}/deployments/helm/openhound/README.md +1 -1
  4. {openhound-0.1.1 → openhound-0.1.3.dev2}/deployments/helm/values.example.yaml +1 -1
  5. openhound-0.1.3.dev2/example-configurations/bloodhound-community/.dlt-example/config.toml +16 -0
  6. openhound-0.1.3.dev2/example-configurations/bloodhound-community/.dlt-example/secrets_github.toml +6 -0
  7. openhound-0.1.3.dev2/example-configurations/bloodhound-community/.dlt-example/secrets_jamf.toml +5 -0
  8. openhound-0.1.3.dev2/example-configurations/bloodhound-community/.dlt-example/secrets_okta.toml +5 -0
  9. openhound-0.1.3.dev2/example-configurations/bloodhound-community/README.md +17 -0
  10. openhound-0.1.3.dev2/example-configurations/bloodhound-community/docker-compose.yml +162 -0
  11. openhound-0.1.3.dev2/example-configurations/bloodhound-enterprise/.dlt-example/config.toml +16 -0
  12. openhound-0.1.3.dev2/example-configurations/bloodhound-enterprise/.dlt-example/secrets_github.toml +12 -0
  13. openhound-0.1.3.dev2/example-configurations/bloodhound-enterprise/.dlt-example/secrets_jamf.toml +11 -0
  14. openhound-0.1.3.dev2/example-configurations/bloodhound-enterprise/.dlt-example/secrets_okta.toml +11 -0
  15. openhound-0.1.3.dev2/example-configurations/bloodhound-enterprise/README.md +16 -0
  16. openhound-0.1.1/docker-compose.bhe.yml → openhound-0.1.3.dev2/example-configurations/bloodhound-enterprise/docker-compose.yml +12 -1
  17. {openhound-0.1.1 → openhound-0.1.3.dev2}/pyproject.toml +1 -1
  18. openhound-0.1.1/docker-compose.yml +0 -63
  19. {openhound-0.1.1 → openhound-0.1.3.dev2}/.github/CODE_OF_CONDUCT.md +0 -0
  20. {openhound-0.1.1 → openhound-0.1.3.dev2}/.github/CONTRIBUTING.md +0 -0
  21. {openhound-0.1.1 → openhound-0.1.3.dev2}/.github/GOVERNANCE.md +0 -0
  22. {openhound-0.1.1 → openhound-0.1.3.dev2}/.github/GitHub-COC-Header.png +0 -0
  23. {openhound-0.1.1 → openhound-0.1.3.dev2}/.github/GitHub-CONTRIB-Header.png +0 -0
  24. {openhound-0.1.1 → openhound-0.1.3.dev2}/.github/GitHub-GOV-Header.png +0 -0
  25. {openhound-0.1.1 → openhound-0.1.3.dev2}/.github/GitHub-Header.png +0 -0
  26. {openhound-0.1.1 → openhound-0.1.3.dev2}/.github/GitHub-LIC-Header.png +0 -0
  27. {openhound-0.1.1 → openhound-0.1.3.dev2}/.github/GitHub-SEC-Header.png +0 -0
  28. {openhound-0.1.1 → openhound-0.1.3.dev2}/.github/OpenHoundDark.svg +0 -0
  29. {openhound-0.1.1 → openhound-0.1.3.dev2}/.github/OpenHoundLight.svg +0 -0
  30. {openhound-0.1.1 → openhound-0.1.3.dev2}/.github/SECURITY.md +0 -0
  31. {openhound-0.1.1 → openhound-0.1.3.dev2}/.github/SO-Dark.svg +0 -0
  32. {openhound-0.1.1 → openhound-0.1.3.dev2}/.github/SO-FOSS-Dark.svg +0 -0
  33. {openhound-0.1.1 → openhound-0.1.3.dev2}/.github/SO-FOSS-Light.svg +0 -0
  34. {openhound-0.1.1 → openhound-0.1.3.dev2}/.github/SO-Light.svg +0 -0
  35. {openhound-0.1.1 → openhound-0.1.3.dev2}/.github/workflows/build-and-publish.yml +0 -0
  36. {openhound-0.1.1 → openhound-0.1.3.dev2}/.github/workflows/release-on-merge.yml +0 -0
  37. {openhound-0.1.1 → openhound-0.1.3.dev2}/.github/workflows/test.yml +0 -0
  38. {openhound-0.1.1 → openhound-0.1.3.dev2}/.github/workflows/validate-branch.yml +0 -0
  39. {openhound-0.1.1 → openhound-0.1.3.dev2}/.gitignore +0 -0
  40. {openhound-0.1.1 → openhound-0.1.3.dev2}/.pre-commit-config.yaml +0 -0
  41. {openhound-0.1.1 → openhound-0.1.3.dev2}/Dockerfile +0 -0
  42. {openhound-0.1.1 → openhound-0.1.3.dev2}/LICENSE.md +0 -0
  43. {openhound-0.1.1 → openhound-0.1.3.dev2}/README.md +0 -0
  44. {openhound-0.1.1 → openhound-0.1.3.dev2}/deployments/helm/openhound/Chart.yaml +0 -0
  45. {openhound-0.1.1 → openhound-0.1.3.dev2}/deployments/helm/openhound/templates/_helpers.tpl +0 -0
  46. {openhound-0.1.1 → openhound-0.1.3.dev2}/deployments/helm/openhound/templates/deployment.yaml +0 -0
  47. {openhound-0.1.1 → openhound-0.1.3.dev2}/deployments/helm/openhound/templates/serviceaccount.yaml +0 -0
  48. {openhound-0.1.1 → openhound-0.1.3.dev2}/deployments/helm/openhound/values.yaml +0 -0
  49. {openhound-0.1.1 → openhound-0.1.3.dev2}/justfile +0 -0
  50. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/__init__.py +0 -0
  51. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/__main__.py +0 -0
  52. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/cli/__init__.py +0 -0
  53. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/cli/collect.py +0 -0
  54. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/cli/convert.py +0 -0
  55. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/cli/create.py +0 -0
  56. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/cli/override.py +0 -0
  57. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/cli/preproc.py +0 -0
  58. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/cli/privilege_zone.py +0 -0
  59. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/cli/saved_search.py +0 -0
  60. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/__init__.py +0 -0
  61. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/app.py +0 -0
  62. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/app.pyi +0 -0
  63. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/asset.py +0 -0
  64. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/clients/__init__.py +0 -0
  65. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/clients/bloodhound.py +0 -0
  66. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/clients/bloodhound_enterprise.py +0 -0
  67. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/clients/models/__init__.py +0 -0
  68. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/clients/models/asset_groups.py +0 -0
  69. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/clients/models/custom_nodes.py +0 -0
  70. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/clients/models/graph_cypher.py +0 -0
  71. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/clients/models/jobs.py +0 -0
  72. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/clients/models/saved_query.py +0 -0
  73. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/collect.py +0 -0
  74. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/context.py +0 -0
  75. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/convert.py +0 -0
  76. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/exceptions.py +0 -0
  77. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/logging.py +0 -0
  78. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/lookup.py +0 -0
  79. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/manager.py +0 -0
  80. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/models/__init__.py +0 -0
  81. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/models/collector.py +0 -0
  82. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/models/entries.py +0 -0
  83. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/models/entries_dataclass.py +0 -0
  84. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/models/extension.py +0 -0
  85. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/models/graph.py +0 -0
  86. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/models/icons.py +0 -0
  87. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/models/privilege_zone.py +0 -0
  88. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/models/saved_search.py +0 -0
  89. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/pipeline.py +0 -0
  90. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/preproc.py +0 -0
  91. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/privilege_zones.py +0 -0
  92. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/progress.py +0 -0
  93. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/resources.py +0 -0
  94. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/core/saved_searches.py +0 -0
  95. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/destinations/__init__.py +0 -0
  96. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/destinations/bloodhound/__init__.py +0 -0
  97. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/destinations/bloodhound/destination.py +0 -0
  98. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/destinations/bloodhound_enterprise/__init__.py +0 -0
  99. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/destinations/bloodhound_enterprise/destination.py +0 -0
  100. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/destinations/opengraph/__init__.py +0 -0
  101. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/destinations/opengraph/destination.py +0 -0
  102. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/docs/__init__.py +0 -0
  103. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/docs/pipeline.py +0 -0
  104. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/docs/templates/asset.md.j2 +0 -0
  105. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/docs/templates/class_table.md.j2 +0 -0
  106. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/docs/templates/edge.md.j2 +0 -0
  107. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/docs/templates/node.md.j2 +0 -0
  108. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/docs/templates/overview.md.j2 +0 -0
  109. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/docs/templates/pipeline.md.j2 +0 -0
  110. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/docs/templates/test +0 -0
  111. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/main.py +0 -0
  112. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/scheduler/__init__.py +0 -0
  113. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/scheduler/dataflow.py +0 -0
  114. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/scheduler/service.py +0 -0
  115. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/sources/__init__.py +0 -0
  116. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/sources/bloodhound_config/__init__.py +0 -0
  117. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/sources/bloodhound_config/source.py +0 -0
  118. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/sources/opengraph/__init__.py +0 -0
  119. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/sources/opengraph/entries.py +0 -0
  120. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/sources/opengraph/guid.py +0 -0
  121. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/sources/opengraph/source.py +0 -0
  122. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/sources/resource_files/__init__.py +0 -0
  123. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/openhound/sources/resource_files/source.py +0 -0
  124. {openhound-0.1.1 → openhound-0.1.3.dev2}/src/scheduler.py +0 -0
  125. {openhound-0.1.1 → openhound-0.1.3.dev2}/tests/__init__.py +0 -0
  126. {openhound-0.1.1 → openhound-0.1.3.dev2}/tests/conftest.py +0 -0
  127. {openhound-0.1.1 → openhound-0.1.3.dev2}/tests/test_bhe_job_scheduling.py +0 -0
  128. {openhound-0.1.1 → openhound-0.1.3.dev2}/tests/test_collect_output_dir.py +0 -0
  129. {openhound-0.1.1 → openhound-0.1.3.dev2}/tests/test_convert_lookup_file.py +0 -0
  130. {openhound-0.1.1 → openhound-0.1.3.dev2}/tests/test_convert_output_dir.py +0 -0
  131. {openhound-0.1.1 → openhound-0.1.3.dev2}/tests/test_create_docs.py +0 -0
  132. {openhound-0.1.1 → openhound-0.1.3.dev2}/tests/test_data/api/jobs/job_end.json +0 -0
  133. {openhound-0.1.1 → openhound-0.1.3.dev2}/tests/test_data/api/jobs/job_start.json +0 -0
  134. {openhound-0.1.1 → openhound-0.1.3.dev2}/tests/test_data/api/jobs/jobs_available_empty.json +0 -0
  135. {openhound-0.1.1 → openhound-0.1.3.dev2}/tests/test_data/api/jobs/jobs_available_with_job.json +0 -0
  136. {openhound-0.1.1 → openhound-0.1.3.dev2}/tests/test_data/api/jobs/jobs_current.json +0 -0
  137. {openhound-0.1.1 → openhound-0.1.3.dev2}/tests/test_data/api/upload/upload_start.json +0 -0
  138. {openhound-0.1.1 → openhound-0.1.3.dev2}/tests/test_data/extensions/pz_selectors/jamf_tenant.json +0 -0
  139. {openhound-0.1.1 → openhound-0.1.3.dev2}/tests/test_data/extensions/saved_searches/jamf_query_by_name.json +0 -0
  140. {openhound-0.1.1 → openhound-0.1.3.dev2}/tests/test_data/sample_graph.json +0 -0
  141. {openhound-0.1.1 → openhound-0.1.3.dev2}/tests/test_docs_pipeline.py +0 -0
  142. {openhound-0.1.1 → openhound-0.1.3.dev2}/tests/test_extensions_format.py +0 -0
  143. {openhound-0.1.1 → openhound-0.1.3.dev2}/tests/test_log_handlers.py +0 -0
  144. {openhound-0.1.1 → openhound-0.1.3.dev2}/tests/test_preproc_default_lookup.py +0 -0
  145. {openhound-0.1.1 → openhound-0.1.3.dev2}/tests/test_pz_selector_sync.py +0 -0
  146. {openhound-0.1.1 → openhound-0.1.3.dev2}/tests/test_resource_def.py +0 -0
  147. {openhound-0.1.1 → openhound-0.1.3.dev2}/tests/test_saved_searches_sync.py +0 -0
  148. {openhound-0.1.1 → openhound-0.1.3.dev2}/uv.lock +0 -0
@@ -19,10 +19,10 @@ jobs:
19
19
  include:
20
20
  - target: cli
21
21
  suffix: ""
22
- publish_latest: true
22
+ latest_tag: "latest"
23
23
  - target: enterprise
24
24
  suffix: "-enterprise"
25
- publish_latest: false
25
+ latest_tag: "latest-enterprise"
26
26
  env:
27
27
  DOCKER_REGISTRY: ${{ vars.DOCKER_REGISTRY }}
28
28
  DOCKER_REPOSITORY: ${{ vars.DOCKER_REPOSITORY }}
@@ -57,8 +57,8 @@ jobs:
57
57
  run: |
58
58
  TAGS="${{ steps.image-ref.outputs.version_tag }}"
59
59
 
60
- if [ "${{ matrix.publish_latest }}" = "true" ]; then
61
- TAGS="${TAGS}"$'\n'"${DOCKER_REGISTRY}/${DOCKER_REPOSITORY}:latest"
60
+ if [ -n "${{ matrix.latest_tag }}" ]; then
61
+ TAGS="${TAGS}"$'\n'"${DOCKER_REGISTRY}/${DOCKER_REPOSITORY}:${{ matrix.latest_tag }}"
62
62
  fi
63
63
 
64
64
  {
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openhound
3
- Version: 0.1.1
3
+ Version: 0.1.3.dev2
4
4
  Summary: OpenGraph collector framework for BloodHound
5
5
  License-File: LICENSE.md
6
6
  Requires-Python: >=3.13
@@ -26,7 +26,7 @@ helm install -f values.yml openhound-<name> ./deployments/helm/openhound
26
26
  # Example values for the JAMF collector
27
27
  image:
28
28
  repository: docker.io/specterops/openhound
29
- tag: "0.1.0-enterprise"
29
+ tag: "latest-enterprise"
30
30
 
31
31
  # Optional environment variables.
32
32
  env:
@@ -1,7 +1,7 @@
1
1
  # Example values for the JAMF collector
2
2
  image:
3
3
  repository: docker.io/specterops/openhound
4
- tag: "0.1.0-enterprise"
4
+ tag: "latest-enterprise"
5
5
 
6
6
  # Optional environment variables.
7
7
  env:
@@ -0,0 +1,16 @@
1
+ # Example configuration: https://bloodhound.specterops.io/openhound/configuration
2
+ [runtime]
3
+ http_show_error_body = true
4
+ log_cli_level = "WARNING"
5
+ log_format = "JSON"
6
+ log_rotate_when = "midnight"
7
+
8
+ [extract]
9
+ workers = 8
10
+
11
+ [normalize]
12
+ workers = 3
13
+
14
+ [load]
15
+ delete_completed_jobs = true
16
+ truncate_staging_dataset = true
@@ -0,0 +1,6 @@
1
+ # Example configuration for github secrets: https://bloodhound.specterops.io/openhound/collectors/github/collect-data#example-configuration
2
+ [sources.source.github.credentials]
3
+ app_id = "myappid"
4
+ client_id = "myclientid"
5
+ key_path = "/app/.dlt/github.pem"
6
+ org_name = "myorgname"
@@ -0,0 +1,5 @@
1
+ # Example configuration for jamf secrets: https://bloodhound.specterops.io/openhound/collectors/jamf/collect-data#example-configuration
2
+ [sources.source.jamf]
3
+ username = "myusername"
4
+ host = "https://tenant.jamfcloud.com"
5
+ password = "mypassword"
@@ -0,0 +1,5 @@
1
+ # Example configuration for okta secrets: https://bloodhound.specterops.io/openhound/collectors/okta/collect-data#example-configuration
2
+ [sources.source.okta.credentials]
3
+ base_url = "https://mytenant.oktapreview.com"
4
+ client_id = "myclientid"
5
+ private_key_path = "/app/.dlt/okta.json"
@@ -0,0 +1,17 @@
1
+ ## Quick-start
2
+
3
+ 1. Copy `.dlt-example` to `${HOME}/.dlt`and `docker-compose.yml` to `${HOME}`.
4
+ 2. Fill in your credentials in the toml files.
5
+ 3. Place any required key files (github.pem, okta.json) in `${HOME}/.dlt`.
6
+ 4. Pull image from SpecterOps Docker Hub: `docker pull specterops/openhound:latest`
7
+ or run to pull from docker-compose.yml: `docker compose pull`
8
+ 5. Run all collectors: `docker compose up -d`
9
+ or run a single one: `docker compose up -d collect-jamf preprocess-jamf convert-jamf`
10
+
11
+ Example docker-compose file for running OpenHound with Jamf, GitHub, and Okta collectors.
12
+ Collector output is written to local bind-mount directories under `./output/<collector>/`.
13
+
14
+ ## WARNING:
15
+ All config and secret files referenced below MUST exist before running
16
+ `docker compose up`. If they are missing, Docker will create them as directories,
17
+ which will cause the collector to fail.
@@ -0,0 +1,162 @@
1
+ x-cli: &cli
2
+ image: specterops/openhound:latest
3
+ restart: no
4
+
5
+ # These environment variables can also be set inside the ~/.dlt/config.toml file
6
+ # and act as an example. Configuring openhound can be done using environment variables,
7
+ # configuration files or a combination of both.
8
+ environment: &env
9
+ LOG_LEVEL: INFO
10
+ EXTRACT__WORKERS: 8
11
+ LOG_CONTAINER: true
12
+
13
+ x-jamf: &jamf
14
+ <<: *cli
15
+ volumes:
16
+ - ${HOME}/.dlt/config.toml:/app/.dlt/config.toml:ro
17
+ - ./output/jamf:/tmp/output
18
+ secrets:
19
+ - source: secrets_jamf
20
+ target: /app/.dlt/secrets.toml
21
+
22
+ x-github: &github
23
+ <<: *cli
24
+ volumes:
25
+ - ${HOME}/.dlt/config.toml:/app/.dlt/config.toml:ro
26
+ - ./output/github:/tmp/output
27
+ secrets:
28
+ - source: secrets_github
29
+ target: /app/.dlt/secrets.toml
30
+ - source: key_github
31
+ target: /app/.dlt/github.pem
32
+
33
+ x-okta: &okta
34
+ <<: *cli
35
+ volumes:
36
+ - ${HOME}/.dlt/config.toml:/app/.dlt/config.toml:ro
37
+ - ./output/okta:/tmp/output
38
+ secrets:
39
+ - source: secrets_okta
40
+ target: /app/.dlt/secrets.toml
41
+ - source: key_okta
42
+ target: /app/.dlt/okta.json
43
+
44
+ services:
45
+ # --- Jamf ---
46
+ collect-jamf:
47
+ <<: *jamf
48
+ command:
49
+ - collect
50
+ - jamf
51
+ - /tmp/output/raw
52
+ - --progress=log
53
+
54
+ preprocess-jamf:
55
+ <<: *jamf
56
+ command:
57
+ - preprocess
58
+ - jamf
59
+ - /tmp/output/raw/jamf
60
+ - /tmp/output/lookup.duckdb
61
+ - --progress=log
62
+ depends_on:
63
+ collect-jamf:
64
+ condition: service_completed_successfully
65
+
66
+ convert-jamf:
67
+ <<: *jamf
68
+ command:
69
+ - convert
70
+ - jamf
71
+ - /tmp/output/raw/jamf
72
+ - /tmp/output/graph
73
+ - --lookup-file=/tmp/output/lookup.duckdb
74
+ - --progress=log
75
+ depends_on:
76
+ preprocess-jamf:
77
+ condition: service_completed_successfully
78
+
79
+ # --- GitHub ---
80
+ collect-github:
81
+ <<: *github
82
+ command:
83
+ - collect
84
+ - github
85
+ - /tmp/output/raw
86
+ - --progress=log
87
+
88
+ preprocess-github:
89
+ <<: *github
90
+ command:
91
+ - preprocess
92
+ - github
93
+ - /tmp/output/raw/github
94
+ - /tmp/output/lookup.duckdb
95
+ - --progress=log
96
+ depends_on:
97
+ collect-github:
98
+ condition: service_completed_successfully
99
+
100
+ convert-github:
101
+ <<: *github
102
+ command:
103
+ - convert
104
+ - github
105
+ - /tmp/output/raw/github
106
+ - /tmp/output/graph
107
+ - --lookup-file=/tmp/output/lookup.duckdb
108
+ - --progress=log
109
+ depends_on:
110
+ preprocess-github:
111
+ condition: service_completed_successfully
112
+
113
+ # --- Okta ---
114
+ collect-okta:
115
+ <<: *okta
116
+ command:
117
+ - collect
118
+ - okta
119
+ - /tmp/output/raw
120
+ - --progress=log
121
+
122
+ preprocess-okta:
123
+ <<: *okta
124
+ command:
125
+ - preprocess
126
+ - okta
127
+ - /tmp/output/raw/okta
128
+ - /tmp/output/lookup.duckdb
129
+ - --progress=log
130
+ depends_on:
131
+ collect-okta:
132
+ condition: service_completed_successfully
133
+
134
+ convert-okta:
135
+ <<: *okta
136
+ command:
137
+ - convert
138
+ - okta
139
+ - /tmp/output/raw/okta
140
+ - /tmp/output/graph
141
+ - --lookup-file=/tmp/output/lookup.duckdb
142
+ - --progress=log
143
+ depends_on:
144
+ preprocess-okta:
145
+ condition: service_completed_successfully
146
+
147
+ secrets:
148
+ # Jamf: username + password auth
149
+ secrets_jamf:
150
+ file: ${HOME}/.dlt/secrets_jamf.toml
151
+
152
+ # GitHub: GitHub App auth (app_id, client_id, org_name) + private key PEM (github.pem)
153
+ secrets_github:
154
+ file: ${HOME}/.dlt/secrets_github.toml
155
+ key_github:
156
+ file: ${HOME}/.dlt/github.pem
157
+
158
+ # Okta: OAuth client credentials (base_url, client_id) + private key JSON (okta.json)
159
+ secrets_okta:
160
+ file: ${HOME}/.dlt/secrets_okta.toml
161
+ key_okta:
162
+ file: ${HOME}/.dlt/okta.json
@@ -0,0 +1,16 @@
1
+ # Example configuration: https://bloodhound.specterops.io/openhound/enterprise#full-configuration-example
2
+ [runtime]
3
+ http_show_error_body = true
4
+ log_cli_level = "WARNING"
5
+ log_format = "JSON"
6
+ log_rotate_when = "midnight"
7
+
8
+ [extract]
9
+ workers = 8
10
+
11
+ [normalize]
12
+ workers = 3
13
+
14
+ [load]
15
+ delete_completed_jobs = true
16
+ truncate_staging_dataset = true
@@ -0,0 +1,12 @@
1
+ [destination.bloodhoundenterprise]
2
+ interval = "300"
3
+ token_id = "client_token_id"
4
+ token_key = "client_token_key"
5
+ url = "bhe_url"
6
+
7
+ # Example configuration for github secrets: https://bloodhound.specterops.io/openhound/collectors/github/collect-data#example-configuration
8
+ [sources.source.github.credentials]
9
+ app_id = "myappid"
10
+ client_id = "myclientid"
11
+ key_path = "/app/.dlt/github.pem"
12
+ org_name = "myorgname"
@@ -0,0 +1,11 @@
1
+ [destination.bloodhoundenterprise]
2
+ interval = "300"
3
+ token_id = "client_token_id"
4
+ token_key = "client_token_key"
5
+ url = "bhe_url"
6
+
7
+ # Example configuration for jamf secrets: https://bloodhound.specterops.io/openhound/collectors/jamf/collect-data#example-configuration
8
+ [sources.source.jamf]
9
+ username = "myusername"
10
+ host = "https://mytenant.jamfcloud.com"
11
+ password = "mypassword"
@@ -0,0 +1,11 @@
1
+ [destination.bloodhoundenterprise]
2
+ interval = "300"
3
+ token_id = "client_token_id"
4
+ token_key = "client_token_key"
5
+ url = "bhe_url"
6
+
7
+ # Example configuration for okta secrets: https://bloodhound.specterops.io/openhound/collectors/okta/collect-data#example-configuration
8
+ [sources.source.okta.credentials]
9
+ base_url = "https://mytenant.oktapreview.com"
10
+ client_id = "myclientid"
11
+ private_key_path = "/app/.dlt/okta.json"
@@ -0,0 +1,16 @@
1
+ ## Quick-start
2
+
3
+ 1. Copy `.dlt-example` to `${HOME}/.dlt`and `docker-compose.yml` to `${HOME}`.
4
+ 2. Fill in your credentials in the toml files.
5
+ 3. Place any required key files (github.pem, okta.json) in `${HOME}/.dlt`.
6
+ 4. Pull image from SpecterOps Docker Hub: `docker pull specterops/openhound:latest-enterprise`
7
+ or run to pull from docker-compose.yml: `docker compose pull`
8
+ 5. Run all collectors: `docker compose up -d`
9
+ or run a single one: `docker compose up -d scheduler-jamf`
10
+
11
+ Full configuration reference: https://bloodhound.specterops.io/openhound/enterprise
12
+
13
+ ## WARNING:
14
+ All config and secret files referenced below MUST exist before running
15
+ `docker compose up`. If they are missing, Docker will create them as directories,
16
+ which will cause the collector to fail.
@@ -1,5 +1,5 @@
1
1
  x-scheduler: &scheduler
2
- image: specterops/openhound:${IMAGE_VERSION:-0.1.0-enterprise}
2
+ image: specterops/openhound:${IMAGE_VERSION:latest-enterprise}
3
3
  restart: unless-stopped
4
4
  init: true
5
5
  volumes:
@@ -14,6 +14,7 @@ x-scheduler: &scheduler
14
14
  LOG_CONTAINER: true
15
15
 
16
16
  services:
17
+ # --- Jamf ---
17
18
  scheduler-jamf:
18
19
  <<: *scheduler
19
20
  environment:
@@ -23,6 +24,7 @@ services:
23
24
  - source: secrets_jamf
24
25
  target: /app/.dlt/secrets.toml
25
26
 
27
+ # --- GitHub ---
26
28
  scheduler-github:
27
29
  <<: *scheduler
28
30
  environment:
@@ -34,6 +36,7 @@ services:
34
36
  - source: key_github
35
37
  target: /app/.dlt/github.pem
36
38
 
39
+ # --- Okta ---
37
40
  scheduler-okta:
38
41
  <<: *scheduler
39
42
  environment:
@@ -46,12 +49,20 @@ services:
46
49
  target: /app/.dlt/okta.json
47
50
 
48
51
  secrets:
52
+ # Copy the .dlt-example folder to ${HOME}/.dlt as a starting point for each secrets file.
53
+ # Each secrets file must also contain [destination.bloodhoundenterprise] with url, token_id, and token_key.
54
+
55
+ # Jamf: username + password auth
49
56
  secrets_jamf:
50
57
  file: ${HOME}/.dlt/secrets_jamf.toml
58
+
59
+ # GitHub: GitHub App auth (app_id, client_id, org_name) + private key PEM (github.pem)
51
60
  secrets_github:
52
61
  file: ${HOME}/.dlt/secrets_github.toml
53
62
  key_github:
54
63
  file: ${HOME}/.dlt/github.pem
64
+
65
+ # Okta: OAuth client credentials (base_url, client_id) + private key JSON (okta.json)
55
66
  secrets_okta:
56
67
  file: ${HOME}/.dlt/secrets_okta.toml
57
68
  key_okta:
@@ -65,7 +65,7 @@ local_scheme = "no-local-version"
65
65
 
66
66
  [dependency-groups]
67
67
  dev = [
68
- "openhound-faker==0.0.4",
68
+ "openhound-faker==0.0.6",
69
69
  "ipython>=9.12.0",
70
70
  "pre-commit>=4.5.1",
71
71
  "pytest>=9.0.1",
@@ -1,63 +0,0 @@
1
- # This is an example docker-compose file for running OpenHound with the JAMF collector.
2
- # the output graph will be stored inside a named volume. You can copy the OpenGraph contents using the
3
- # following command: `<docker|podman> cp <container_name>:/tmp/output/graph <destination_path>`
4
-
5
- x-cli: &cli
6
- image: specterops/openhound:latest
7
- restart: no
8
- volumes:
9
- - ${HOME}/.dlt/config.toml:/app/.dlt/config.toml:ro
10
- - jamf-output:/tmp/output
11
-
12
- # These environment variables can also be set inside the ~/.dlt/config.toml file
13
- # and act as an example. Configuring openhound can be done using environment variables,
14
- # configuration files or a combination of both.
15
- environment: &env
16
- LOG_LEVEL: INFO
17
- EXTRACT__WORKERS: 8
18
- LOG_CONTAINER: true
19
-
20
- secrets:
21
- - source: secrets_jamf
22
- target: /app/.dlt/secrets.toml
23
-
24
- services:
25
- collect-jamf:
26
- <<: *cli
27
- command:
28
- - collect
29
- - jamf
30
- - /tmp/output/raw
31
- - --progress=log
32
-
33
- preprocess-jamf:
34
- <<: *cli
35
- command:
36
- - preprocess
37
- - jamf
38
- - /tmp/output/raw/jamf
39
- - /tmp/output/lookup.duckdb
40
- - --progress=log
41
- depends_on:
42
- collect-jamf:
43
- condition: service_completed_successfully
44
-
45
- convert-jamf:
46
- <<: *cli
47
- command:
48
- - convert
49
- - jamf
50
- - /tmp/output/raw/jamf
51
- - /tmp/output/graph
52
- - --lookup-file=/tmp/output/lookup.duckdb
53
- - --progress=log
54
- depends_on:
55
- preprocess-jamf:
56
- condition: service_completed_successfully
57
-
58
- volumes:
59
- jamf-output:
60
-
61
- secrets:
62
- secrets_jamf:
63
- file: ${HOME}/.dlt/secrets_jamf.toml
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes