openhound-github 0.21.2__tar.gz → 0.22.0__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 (453) hide show
  1. {openhound_github-0.21.2 → openhound_github-0.22.0}/.github/workflows/publish-container.yml +28 -0
  2. {openhound_github-0.21.2 → openhound_github-0.22.0}/.gitignore +5 -0
  3. openhound_github-0.21.2/README.md → openhound_github-0.22.0/PKG-INFO +20 -1
  4. openhound_github-0.21.2/PKG-INFO → openhound_github-0.22.0/README.md +9 -12
  5. openhound_github-0.22.0/descriptions/edges/GH_Owns.md +29 -0
  6. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_App.md +8 -0
  7. openhound_github-0.22.0/docker-compose/.dlt/config.toml.example +5 -0
  8. openhound_github-0.22.0/docker-compose/.dlt/secrets.toml.example +12 -0
  9. openhound_github-0.22.0/docker-compose/.env.example +2 -0
  10. openhound_github-0.22.0/docker-compose/README.md +150 -0
  11. openhound_github-0.22.0/docker-compose/check_config.py +54 -0
  12. openhound_github-0.22.0/docker-compose/compose.yaml +62 -0
  13. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/schema.json +1 -1
  14. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/lookup.py +32 -0
  15. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/app_installation.py +90 -5
  16. openhound_github-0.22.0/tests/test_app_model.py +121 -0
  17. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_lookup.py +38 -0
  18. openhound_github-0.21.2/descriptions/edges/GH_Owns.md +0 -20
  19. {openhound_github-0.21.2 → openhound_github-0.22.0}/.dockerignore +0 -0
  20. {openhound_github-0.21.2 → openhound_github-0.22.0}/.github/CODE_OF_CONDUCT.md +0 -0
  21. {openhound_github-0.21.2 → openhound_github-0.22.0}/.github/CONTRIBUTING.md +0 -0
  22. {openhound_github-0.21.2 → openhound_github-0.22.0}/.github/GOVERNANCE.md +0 -0
  23. {openhound_github-0.21.2 → openhound_github-0.22.0}/.github/SECURITY.md +0 -0
  24. {openhound_github-0.21.2 → openhound_github-0.22.0}/.github/SO-Dark.svg +0 -0
  25. {openhound_github-0.21.2 → openhound_github-0.22.0}/.github/SO-FOSS-Dark.svg +0 -0
  26. {openhound_github-0.21.2 → openhound_github-0.22.0}/.github/SO-FOSS-Light.svg +0 -0
  27. {openhound_github-0.21.2 → openhound_github-0.22.0}/.github/SO-Light.svg +0 -0
  28. {openhound_github-0.21.2 → openhound_github-0.22.0}/.github/workflows/publish.yml +0 -0
  29. {openhound_github-0.21.2 → openhound_github-0.22.0}/.github/workflows/release-on-merge.yml +0 -0
  30. {openhound_github-0.21.2 → openhound_github-0.22.0}/.github/workflows/validate-branch.yml +0 -0
  31. {openhound_github-0.21.2 → openhound_github-0.22.0}/.pre-commit-config.yaml +0 -0
  32. {openhound_github-0.21.2 → openhound_github-0.22.0}/Dockerfile +0 -0
  33. {openhound_github-0.21.2 → openhound_github-0.22.0}/LICENSE.md +0 -0
  34. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_AddAssignee.md +0 -0
  35. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_AddCollaborator.md +0 -0
  36. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_AddLabel.md +0 -0
  37. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_AddMember.md +0 -0
  38. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_AddedDeployKey.md +0 -0
  39. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_AdminTo.md +0 -0
  40. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ApprovesDeploymentTo.md +0 -0
  41. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_AssignedTo.md +0 -0
  42. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_AuthorizedForOrganization.md +0 -0
  43. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_BypassBranchProtection.md +0 -0
  44. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_BypassPullRequestAllowances.md +0 -0
  45. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CallsWorkflow.md +0 -0
  46. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanAccess.md +0 -0
  47. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanAccessSecret.md +0 -0
  48. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanAssumeIdentity.md +0 -0
  49. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanCreateBranch.md +0 -0
  50. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanCreateEnvironment.md +0 -0
  51. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanCreateInternalRepositories.md +0 -0
  52. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanCreatePrivateRepositories.md +0 -0
  53. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanCreatePublicRepositories.md +0 -0
  54. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanCreateRepositories.md +0 -0
  55. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanCreateRepositoryWithRunnerAccess.md +0 -0
  56. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanDeployToEnvironment.md +0 -0
  57. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanEditEnvironment.md +0 -0
  58. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanEditProtection.md +0 -0
  59. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanInterceptJob.md +0 -0
  60. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanPwnRequest.md +0 -0
  61. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanReadSecret.md +0 -0
  62. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanReadSecretScanningAlert.md +0 -0
  63. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanRequestOIDCTokenFor.md +0 -0
  64. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanUseRunner.md +0 -0
  65. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanWriteBranch.md +0 -0
  66. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CloseDiscussion.md +0 -0
  67. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CloseIssue.md +0 -0
  68. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ClosePullRequest.md +0 -0
  69. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_Contains.md +0 -0
  70. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ConvertIssuesToDiscussions.md +0 -0
  71. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CreateDiscussionCategory.md +0 -0
  72. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CreateEnterpriseOrganizations.md +0 -0
  73. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CreateRepository.md +0 -0
  74. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CreateSoloMergeQueueEntry.md +0 -0
  75. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CreateTag.md +0 -0
  76. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CreateTeam.md +0 -0
  77. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_DeleteAlertsCodeScanning.md +0 -0
  78. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_DeleteDiscussion.md +0 -0
  79. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_DeleteDiscussionComment.md +0 -0
  80. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_DeleteIssue.md +0 -0
  81. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_DeleteTag.md +0 -0
  82. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_DependsOn.md +0 -0
  83. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_DeploysTo.md +0 -0
  84. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_EditCategoryOnDiscussion.md +0 -0
  85. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_EditDiscussionCategory.md +0 -0
  86. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_EditDiscussionComment.md +0 -0
  87. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_EditEnterpriseCustomPropertiesForOrganizations.md +0 -0
  88. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_EditRepoAnnouncementBanners.md +0 -0
  89. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_EditRepoCustomPropertiesValues.md +0 -0
  90. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_EditRepoMetadata.md +0 -0
  91. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_EditRepoProtections.md +0 -0
  92. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_HasBaseRole.md +0 -0
  93. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_HasExternalIdentity.md +0 -0
  94. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_HasMember.md +0 -0
  95. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_HasPersonalAccessToken.md +0 -0
  96. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_HasPersonalAccessTokenRequest.md +0 -0
  97. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_HasRole.md +0 -0
  98. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_HasRunner.md +0 -0
  99. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_HasSamlIdentityProvider.md +0 -0
  100. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_HasSecret.md +0 -0
  101. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_HasVariable.md +0 -0
  102. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_InheritedFrom.md +0 -0
  103. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_InstalledAs.md +0 -0
  104. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_InviteMember.md +0 -0
  105. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_IsEligibleFor.md +0 -0
  106. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_JumpMergeQueue.md +0 -0
  107. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageDeployKeys.md +0 -0
  108. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageDiscussionBadges.md +0 -0
  109. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageEnterpriseAdmins.md +0 -0
  110. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageEnterpriseIdentityProvider.md +0 -0
  111. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageEnterpriseMembers.md +0 -0
  112. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageEnterpriseOrganizationAdmins.md +0 -0
  113. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageEnterpriseOrganizations.md +0 -0
  114. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageEnterpriseReferrals.md +0 -0
  115. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageEnterpriseTeams.md +0 -0
  116. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageOrganizationWebhooks.md +0 -0
  117. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageRepoSecurityProducts.md +0 -0
  118. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageSecurityProducts.md +0 -0
  119. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageSettingsMergeTypes.md +0 -0
  120. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageSettingsPages.md +0 -0
  121. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageSettingsProjects.md +0 -0
  122. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageSettingsWiki.md +0 -0
  123. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageTopics.md +0 -0
  124. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageWebhooks.md +0 -0
  125. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_MapsToUser.md +0 -0
  126. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_MarkAsDuplicate.md +0 -0
  127. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_MatchesEnvironmentPolicy.md +0 -0
  128. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_MemberOf.md +0 -0
  129. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_OrgBypassCodeScanningDismissalRequests.md +0 -0
  130. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_OrgBypassSecretScanningClosureRequests.md +0 -0
  131. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_OrgReviewAndManageSecretScanningBypassRequests.md +0 -0
  132. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_OrgReviewAndManageSecretScanningClosureRequests.md +0 -0
  133. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ProtectedBy.md +0 -0
  134. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_PushProtectedBranch.md +0 -0
  135. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ReadCodeScanning.md +0 -0
  136. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ReadEnterpriseAuditLog.md +0 -0
  137. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ReadEnterpriseDomainVerification.md +0 -0
  138. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ReadEnterpriseMembers.md +0 -0
  139. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ReadEnterpriseOrgProjects.md +0 -0
  140. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ReadEnterpriseOrganizationAdmin.md +0 -0
  141. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ReadOrganizationActionsUsageMetrics.md +0 -0
  142. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ReadOrganizationCustomOrgRole.md +0 -0
  143. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ReadOrganizationCustomRepoRole.md +0 -0
  144. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ReadRepoContents.md +0 -0
  145. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_RemoveAssignee.md +0 -0
  146. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_RemoveLabel.md +0 -0
  147. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ReopenDiscussion.md +0 -0
  148. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ReopenIssue.md +0 -0
  149. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ReopenPullRequest.md +0 -0
  150. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_RequestPrReview.md +0 -0
  151. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_RequestsAccessTo.md +0 -0
  152. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ResolveDependabotAlerts.md +0 -0
  153. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ResolveSecretScanningAlerts.md +0 -0
  154. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_RestrictionsCanPush.md +0 -0
  155. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_RunOrgMigration.md +0 -0
  156. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_RunsOn.md +0 -0
  157. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ScopedTo.md +0 -0
  158. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_SetEnterpriseInteractionLimits.md +0 -0
  159. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_SetInteractionLimits.md +0 -0
  160. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_SetIssueType.md +0 -0
  161. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_SetMilestone.md +0 -0
  162. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_SetSocialPreview.md +0 -0
  163. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_SyncedTo.md +0 -0
  164. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ToggleDiscussionAnswer.md +0 -0
  165. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ToggleDiscussionCommentMinimize.md +0 -0
  166. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_TransferRepository.md +0 -0
  167. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_UsesSecret.md +0 -0
  168. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_UsesVariable.md +0 -0
  169. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ValidToken.md +0 -0
  170. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ViewDependabotAlerts.md +0 -0
  171. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ViewEnterpriseActionsUsageMetrics.md +0 -0
  172. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ViewEnterpriseBilling.md +0 -0
  173. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ViewEnterpriseSecretScanningAlerts.md +0 -0
  174. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ViewSecretScanningAlerts.md +0 -0
  175. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_WriteCodeScanning.md +0 -0
  176. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_WriteEnterpriseActionsPolicies.md +0 -0
  177. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_WriteEnterpriseBilling.md +0 -0
  178. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_WriteEnterprisePersonalAccessTokenPolicies.md +0 -0
  179. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_WriteEnterpriseSso.md +0 -0
  180. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_WriteEnterpriseTeamMembers.md +0 -0
  181. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_WriteOrganizationActionsSecrets.md +0 -0
  182. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_WriteOrganizationActionsSettings.md +0 -0
  183. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_WriteOrganizationActionsVariables.md +0 -0
  184. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_WriteOrganizationCustomOrgRole.md +0 -0
  185. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_WriteOrganizationCustomRepoRole.md +0 -0
  186. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_WriteOrganizationNetworkConfigurations.md +0 -0
  187. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_WriteRepoContents.md +0 -0
  188. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_WriteRepoPullRequests.md +0 -0
  189. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_AppInstallation.md +0 -0
  190. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_Branch.md +0 -0
  191. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_BranchProtectionRule.md +0 -0
  192. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_ClassicPersonalAccessToken.md +0 -0
  193. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_DeployKey.md +0 -0
  194. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_Enterprise.md +0 -0
  195. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_EnterpriseManagedUser.md +0 -0
  196. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_EnterpriseRole.md +0 -0
  197. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_EnterpriseRunner.md +0 -0
  198. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_EnterpriseRunnerGroup.md +0 -0
  199. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_EnterpriseTeam.md +0 -0
  200. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_Environment.md +0 -0
  201. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_EnvironmentBranchPolicy.md +0 -0
  202. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_EnvironmentSecret.md +0 -0
  203. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_EnvironmentVariable.md +0 -0
  204. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_ExternalIdentity.md +0 -0
  205. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_OrgRole.md +0 -0
  206. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_OrgRunner.md +0 -0
  207. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_OrgRunnerGroup.md +0 -0
  208. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_OrgSecret.md +0 -0
  209. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_OrgVariable.md +0 -0
  210. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_Organization.md +0 -0
  211. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_PersonalAccessToken.md +0 -0
  212. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_PersonalAccessTokenRequest.md +0 -0
  213. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_RepoRole.md +0 -0
  214. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_RepoRunner.md +0 -0
  215. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_RepoSecret.md +0 -0
  216. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_RepoVariable.md +0 -0
  217. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_Repository.md +0 -0
  218. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_Runner.md +0 -0
  219. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_RunnerGroup.md +0 -0
  220. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_SamlIdentityProvider.md +0 -0
  221. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_Scope.md +0 -0
  222. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_Secret.md +0 -0
  223. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_SecretScanningAlert.md +0 -0
  224. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_Team.md +0 -0
  225. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_TeamRole.md +0 -0
  226. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_User.md +0 -0
  227. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_Variable.md +0 -0
  228. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_Workflow.md +0 -0
  229. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_WorkflowJob.md +0 -0
  230. {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_WorkflowStep.md +0 -0
  231. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/privilege_zone_rules/t0-all-repo-admin-role.json +0 -0
  232. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/privilege_zone_rules/t0-app-installations-all-repos.json +0 -0
  233. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/privilege_zone_rules/t0-apps-all-repos.json +0 -0
  234. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/privilege_zone_rules/t0-enterprise-owners-role.json +0 -0
  235. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/privilege_zone_rules/t0-external-identities-owners.json +0 -0
  236. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/privilege_zone_rules/t0-organizations.json +0 -0
  237. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/privilege_zone_rules/t0-owner-users.json +0 -0
  238. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/privilege_zone_rules/t0-owners-role.json +0 -0
  239. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/privilege_zone_rules/t0-pats-all-repos.json +0 -0
  240. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/privilege_zone_rules/t0-privilege-escalation-roles.json +0 -0
  241. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/privilege_zone_rules/t0-privilege-escalation-users.json +0 -0
  242. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/privilege_zone_rules/t0-saml-identity-providers.json +0 -0
  243. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/README.md +0 -0
  244. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/actions-sha-pinning-not-required.json +0 -0
  245. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/active-leaked-secrets.json +0 -0
  246. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/advanced-security-disabled-new-repos.json +0 -0
  247. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/all-actions-allowed.json +0 -0
  248. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/app-installations-all-repos.json +0 -0
  249. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/branch-protection-admins-not-enforced.json +0 -0
  250. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/branch-protection-deletions-allowed.json +0 -0
  251. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/branch-protection-force-pushes.json +0 -0
  252. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/branch-protection-no-code-owner-reviews.json +0 -0
  253. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/branch-protection-no-pr-reviews.json +0 -0
  254. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/branch-protection-no-status-checks.json +0 -0
  255. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/branch-protection-self-approval.json +0 -0
  256. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/branch-protection-stale-reviews.json +0 -0
  257. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/bypass-pr-requirements.json +0 -0
  258. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/dangerous-branch-perms.json +0 -0
  259. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/default-repository-permissions.json +0 -0
  260. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/demo-sso-to-cloud-round-trip.json +0 -0
  261. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/dependabot-alerts-disabled-new-repos.json +0 -0
  262. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/dependabot-updates-disabled-new-repos.json +0 -0
  263. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/dependency-graph-disabled-new-repos.json +0 -0
  264. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/environments-admin-bypass.json +0 -0
  265. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/expired-pats.json +0 -0
  266. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/external-identities-without-scim.json +0 -0
  267. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/github-to-azure-identity.json +0 -0
  268. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/global-repo-perms.json +0 -0
  269. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/hybrid-identities.json +0 -0
  270. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/members-can-change-repo-visibility.json +0 -0
  271. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/members-can-create-pages.json +0 -0
  272. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/members-can-create-public-repos.json +0 -0
  273. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/members-can-delete-repos.json +0 -0
  274. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/members-can-fork-private-repos.json +0 -0
  275. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/members-can-invite-outside-collaborators.json +0 -0
  276. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/org-owners.json +0 -0
  277. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/orgs-without-2fa.json +0 -0
  278. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/pats-all-repo-access.json +0 -0
  279. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/pending-pat-requests.json +0 -0
  280. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/private-repos-forking-allowed.json +0 -0
  281. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/privileged-custom-org-roles.json +0 -0
  282. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/privileged-hybrid-identities.json +0 -0
  283. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/public-repos.json +0 -0
  284. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/push-protection-disabled-new-repos.json +0 -0
  285. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/push-to-protected-branches.json +0 -0
  286. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/repos-secret-scanning-disabled.json +0 -0
  287. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/repos-vulnerable-to-workflow-secret-exfil.json +0 -0
  288. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/repository-workflows.json +0 -0
  289. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/saml-configuration.json +0 -0
  290. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/secret-scanning-alerts.json +0 -0
  291. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/secret-scanning-disabled-new-repos.json +0 -0
  292. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/secrets-reachable-by-user.json +0 -0
  293. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/self-hosted-runners-can-intercept-broad-token-jobs.json +0 -0
  294. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/shared-self-hosted-runners-can-intercept-secret-bearing-jobs.json +0 -0
  295. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/team-membership-admin.json +0 -0
  296. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/team-structure.json +0 -0
  297. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/unprotected-branches.json +0 -0
  298. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/unprotected-default-branch-with-workflow.json +0 -0
  299. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/unprotected-default-branches.json +0 -0
  300. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/web-commit-signoff-not-required.json +0 -0
  301. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/workflow-jobs-interceptable-by-self-hosted-runners.json +0 -0
  302. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/workflow-jobs-with-broad-token-write-permissions.json +0 -0
  303. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/workflow-jobs-with-id-token-write-on-self-hosted-runners.json +0 -0
  304. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/workflow-jobs-with-id-token-write.json +0 -0
  305. {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/workflow-jobs-with-observed-oidc-auth-steps.json +0 -0
  306. {openhound_github-0.21.2 → openhound_github-0.22.0}/justfile +0 -0
  307. {openhound_github-0.21.2 → openhound_github-0.22.0}/pyproject.toml +0 -0
  308. {openhound_github-0.21.2 → openhound_github-0.22.0}/scripts/generate_gh_description_docs.py +0 -0
  309. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/main.py +0 -0
  310. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/__init__.py +0 -0
  311. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/auth.py +0 -0
  312. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/extension.yaml +0 -0
  313. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/github_rest_client.py +0 -0
  314. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/github_retry.py +0 -0
  315. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/graph.py +0 -0
  316. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/graphql.py +0 -0
  317. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/helpers.py +0 -0
  318. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/kinds/edges.py +0 -0
  319. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/kinds/nodes.py +0 -0
  320. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/main.py +0 -0
  321. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/__init__.py +0 -0
  322. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/actions_permission.py +0 -0
  323. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/branch.py +0 -0
  324. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/branch_pr_bypass_allowance.py +0 -0
  325. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/branch_protection_rule.py +0 -0
  326. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/branch_push_allowance.py +0 -0
  327. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/classic_personal_access_token.py +0 -0
  328. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/deploy_key.py +0 -0
  329. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise.py +0 -0
  330. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise_admin.py +0 -0
  331. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise_credential_inventory.py +0 -0
  332. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise_helpers.py +0 -0
  333. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise_managed_user.py +0 -0
  334. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise_member.py +0 -0
  335. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise_organization.py +0 -0
  336. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise_role.py +0 -0
  337. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise_role_team.py +0 -0
  338. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise_role_user.py +0 -0
  339. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise_team.py +0 -0
  340. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise_team_member.py +0 -0
  341. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise_team_organization.py +0 -0
  342. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise_team_role.py +0 -0
  343. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise_user.py +0 -0
  344. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/env_secret.py +0 -0
  345. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/env_variable.py +0 -0
  346. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/environment.py +0 -0
  347. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/environment_branch_policy.py +0 -0
  348. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/external_identity.py +0 -0
  349. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/org.py +0 -0
  350. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/org_role.py +0 -0
  351. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/org_role_member.py +0 -0
  352. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/org_role_team.py +0 -0
  353. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/org_secret.py +0 -0
  354. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/org_variable.py +0 -0
  355. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/permissions.py +0 -0
  356. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/personal_access_token.py +0 -0
  357. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/personal_access_token_access.py +0 -0
  358. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/personal_access_token_request.py +0 -0
  359. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/projected_enterprise_team.py +0 -0
  360. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/repo_role_assignment.py +0 -0
  361. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/repository.py +0 -0
  362. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/repository_role.py +0 -0
  363. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/repository_secret.py +0 -0
  364. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/repository_variable.py +0 -0
  365. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/runner.py +0 -0
  366. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/saml_assertion_consumer_service.py +0 -0
  367. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/saml_helpers.py +0 -0
  368. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/saml_issuer.py +0 -0
  369. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/saml_provider.py +0 -0
  370. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/saml_service_provider.py +0 -0
  371. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/scim_user.py +0 -0
  372. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/scope.py +0 -0
  373. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/secret_scanning_alert.py +0 -0
  374. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/team.py +0 -0
  375. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/team_member.py +0 -0
  376. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/team_role.py +0 -0
  377. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/user.py +0 -0
  378. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/workflow.py +0 -0
  379. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/workflow_job.py +0 -0
  380. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/workflow_reference.py +0 -0
  381. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/workflow_step.py +0 -0
  382. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/resources/__init__.py +0 -0
  383. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/resources/enterprise.py +0 -0
  384. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/resources/organization.py +0 -0
  385. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/runner_ids.py +0 -0
  386. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/source.py +0 -0
  387. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/transforms.py +0 -0
  388. {openhound_github-0.21.2 → openhound_github-0.22.0}/src/scheduler.py +0 -0
  389. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_app_auth.py +0 -0
  390. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_app_installation_repo_access.py +0 -0
  391. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_branch_collection_gate.py +0 -0
  392. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_branch_protection_traversability.py +0 -0
  393. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_classic_personal_access_tokens.py +0 -0
  394. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_credential_permission_models.py +0 -0
  395. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/actions-permissions.json +0 -0
  396. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/actionsecrets.json +0 -0
  397. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/app.json +0 -0
  398. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/appinstalls.json +0 -0
  399. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/branch-policies.json +0 -0
  400. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/branch-prot-rules.json +0 -0
  401. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/branches.json +0 -0
  402. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/custom-roles.json +0 -0
  403. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/environments.json +0 -0
  404. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/org-pat-request.json +0 -0
  405. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/org-pat.json +0 -0
  406. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/org-role-teams.json +0 -0
  407. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/org-role-users.json +0 -0
  408. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/org-roles.json +0 -0
  409. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/org.json +0 -0
  410. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/pat-repositories.json +0 -0
  411. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/repo-collaborators.json +0 -0
  412. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/repo-teams.json +0 -0
  413. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/repositories.json +0 -0
  414. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/scimusers.json +0 -0
  415. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/secrets.json +0 -0
  416. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/secretscanningalert.json +0 -0
  417. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/selected-org-secrets.json +0 -0
  418. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/variables.json +0 -0
  419. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/workflows.json +0 -0
  420. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_deploy_key_models.py +0 -0
  421. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_deploy_key_resources.py +0 -0
  422. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_description_docs.py +0 -0
  423. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_enterprise_capabilities.py +0 -0
  424. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_enterprise_organization.py +0 -0
  425. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_enterprise_resources.py +0 -0
  426. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_environment_model.py +0 -0
  427. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_environment_resources.py +0 -0
  428. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_environment_reviewer_lookup.py +0 -0
  429. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_error_resilience.py +0 -0
  430. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_github_app_retry.py +0 -0
  431. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_github_rest_client.py +0 -0
  432. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_github_retry.py +0 -0
  433. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_helpers.py +0 -0
  434. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_org_role_model.py +0 -0
  435. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_org_scim_resources.py +0 -0
  436. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_org_secret_models.py +0 -0
  437. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_preproc.py +0 -0
  438. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_repository_rulesets.py +0 -0
  439. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_repository_scopes.py +0 -0
  440. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_runner_ids.py +0 -0
  441. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_runner_models.py +0 -0
  442. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_runner_resources.py +0 -0
  443. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_saml_helpers.py +0 -0
  444. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_saml_models.py +0 -0
  445. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_scim_models.py +0 -0
  446. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_source_endpoints.py +0 -0
  447. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_source_org_canonicalization.py +0 -0
  448. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_team_external_groups.py +0 -0
  449. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_variable_models.py +0 -0
  450. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_workflow_interception_path.py +0 -0
  451. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_workflow_model.py +0 -0
  452. {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_workflow_resources.py +0 -0
  453. {openhound_github-0.21.2 → openhound_github-0.22.0}/uv.lock +0 -0
@@ -56,6 +56,7 @@ jobs:
56
56
  if [[ "$TARGET" == cli ]]; then SUFFIX="-cli"; fi
57
57
  echo "version=$VERSION" >> "$GITHUB_OUTPUT"
58
58
  echo "tag=$IMAGE:$VERSION$SUFFIX" >> "$GITHUB_OUTPUT"
59
+ echo "latest_tag=$IMAGE:latest$SUFFIX" >> "$GITHUB_OUTPUT"
59
60
 
60
61
  - name: Set up QEMU
61
62
  uses: docker/setup-qemu-action@v4
@@ -125,3 +126,30 @@ jobs:
125
126
  build-args: |
126
127
  COLLECTOR_VERSION=${{ steps.image.outputs.version }}
127
128
  cache-from: type=gha,scope=${{ matrix.target }}
129
+
130
+ - name: Update latest alias for newest release
131
+ env:
132
+ RELEASE_TAG: ${{ inputs.tag }}
133
+ VERSIONED_TAG: ${{ steps.image.outputs.tag }}
134
+ LATEST_TAG: ${{ steps.image.outputs.latest_tag }}
135
+ run: |
136
+ NEWEST_RELEASE_TAG=$(
137
+ git ls-remote --refs --tags origin 'refs/tags/v*' |
138
+ awk '$2 ~ /^refs\/tags\/v[0-9]+\.[0-9]+\.[0-9]+$/ {
139
+ sub("^refs/tags/", "", $2)
140
+ print $2
141
+ }' |
142
+ sort -V |
143
+ tail -n 1
144
+ )
145
+ if [[ -z "$NEWEST_RELEASE_TAG" ]]; then
146
+ echo "Unable to determine the newest release tag" >&2
147
+ exit 1
148
+ fi
149
+ if [[ "$RELEASE_TAG" != "$NEWEST_RELEASE_TAG" ]]; then
150
+ echo "Skipping $LATEST_TAG: newest release is $NEWEST_RELEASE_TAG"
151
+ exit 0
152
+ fi
153
+ docker buildx imagetools create \
154
+ --tag "$LATEST_TAG" \
155
+ "$VERSIONED_TAG"
@@ -22,6 +22,11 @@ __pycache__/
22
22
  *.py[codz]
23
23
  *$py.class
24
24
  .dlt
25
+ # Publish only the Compose configuration examples, never local credentials.
26
+ !/docker-compose/.dlt/
27
+ /docker-compose/.dlt/*
28
+ !/docker-compose/.dlt/config.toml.example
29
+ !/docker-compose/.dlt/secrets.toml.example
25
30
  # C extensions
26
31
  *.so
27
32
 
@@ -1,3 +1,14 @@
1
+ Metadata-Version: 2.5
2
+ Name: openhound-github
3
+ Version: 0.22.0
4
+ Summary: Github collector for OpenHound
5
+ Author-email: "jdreijer@specterops.io" <jdreijer@specterops.io>, Jared Atkinson <jatkinson@specterops.io>
6
+ License-File: LICENSE.md
7
+ Requires-Python: >=3.13
8
+ Requires-Dist: joserfc>=1.6.5
9
+ Requires-Dist: requests>=2.33.0
10
+ Description-Content-Type: text/markdown
11
+
1
12
  <p align="center">
2
13
  <a href="https://specterops.io" target="_blank">
3
14
  <img alt="A project powered by SpecterOps - Creators of BloodHound" src="https://raw.githubusercontent.com/SpecterOps/OpenHound/refs/heads/main/.github/GitHub-Header.png" width="100%" style="max-width: 100%;">
@@ -157,10 +168,18 @@ tag pushes. Both images use the same release version:
157
168
 
158
169
  For example, release tag `v0.20.0` produces image tags `0.20.0` and `0.20.0-cli`.
159
170
  Use a version containing the container files; releases predating this workflow
160
- cannot be built without backporting those files. No moving `latest` tag is published.
171
+ cannot be built without backporting those files.
172
+
173
+ Each release also updates `latest` for the scheduler and `latest-cli` for the
174
+ CLI. These aliases point to the same images as that release's versioned tags.
175
+ Use versioned tags to pin a deployment. To update a Compose deployment using
176
+ `latest`, run `docker compose pull` followed by `docker compose up -d`.
161
177
 
162
178
  ### Run the scheduler
163
179
 
180
+ For a complete Compose setup with configuration templates, persistent storage,
181
+ and a preflight check, see [docker-compose/README.md](docker-compose/README.md).
182
+
164
183
  Prepare your `.dlt/config.toml`, `.dlt/secrets.toml`, and GitHub App private key
165
184
  following the collector configuration documentation above. Mount the directory
166
185
  read-only and use the container path for the key (for example,
@@ -1,14 +1,3 @@
1
- Metadata-Version: 2.5
2
- Name: openhound-github
3
- Version: 0.21.2
4
- Summary: Github collector for OpenHound
5
- Author-email: "jdreijer@specterops.io" <jdreijer@specterops.io>, Jared Atkinson <jatkinson@specterops.io>
6
- License-File: LICENSE.md
7
- Requires-Python: >=3.13
8
- Requires-Dist: joserfc>=1.6.5
9
- Requires-Dist: requests>=2.33.0
10
- Description-Content-Type: text/markdown
11
-
12
1
  <p align="center">
13
2
  <a href="https://specterops.io" target="_blank">
14
3
  <img alt="A project powered by SpecterOps - Creators of BloodHound" src="https://raw.githubusercontent.com/SpecterOps/OpenHound/refs/heads/main/.github/GitHub-Header.png" width="100%" style="max-width: 100%;">
@@ -168,10 +157,18 @@ tag pushes. Both images use the same release version:
168
157
 
169
158
  For example, release tag `v0.20.0` produces image tags `0.20.0` and `0.20.0-cli`.
170
159
  Use a version containing the container files; releases predating this workflow
171
- cannot be built without backporting those files. No moving `latest` tag is published.
160
+ cannot be built without backporting those files.
161
+
162
+ Each release also updates `latest` for the scheduler and `latest-cli` for the
163
+ CLI. These aliases point to the same images as that release's versioned tags.
164
+ Use versioned tags to pin a deployment. To update a Compose deployment using
165
+ `latest`, run `docker compose pull` followed by `docker compose up -d`.
172
166
 
173
167
  ### Run the scheduler
174
168
 
169
+ For a complete Compose setup with configuration templates, persistent storage,
170
+ and a preflight check, see [docker-compose/README.md](docker-compose/README.md).
171
+
175
172
  Prepare your `.dlt/config.toml`, `.dlt/secrets.toml`, and GitHub App private key
176
173
  following the collector configuration documentation above. Mount the directory
177
174
  read-only and use the container path for the key (for example,
@@ -0,0 +1,29 @@
1
+ # GH_Owns
2
+
3
+ ## General Information
4
+
5
+ The traversable GH_Owns edge represents that a GitHub account owns an application or repository. For GitHub Apps, ownership identifies the account whose authorized administrators can manage the App registration and credentials. For repositories, ownership links the repository to its organization. These control relationships are traversable for attack-path analysis.
6
+
7
+ ## Edge Schema
8
+
9
+ | Source | Destination | Traversable |
10
+ | --- | --- | --- |
11
+ | `GH_Enterprise` | `GH_App` | `true` |
12
+ | `GH_Organization` | `GH_App` | `true` |
13
+ | `GH_Organization` | `GH_Repository` | `true` |
14
+ | `GH_User` | `GH_App` | `true` |
15
+
16
+ ## Diagram
17
+
18
+ ```mermaid
19
+ graph LR
20
+ n0["GH_Enterprise"]
21
+ n1["GH_App"]
22
+ n2["GH_Organization"]
23
+ n3["GH_Repository"]
24
+ n4["GH_User"]
25
+ n0 -->|GH_Owns| n1
26
+ n2 -->|GH_Owns| n1
27
+ n2 -->|GH_Owns| n3
28
+ n4 -->|GH_Owns| n1
29
+ ```
@@ -24,10 +24,12 @@ App definitions are retrieved via the public `GET /apps/{app_slug}` endpoint (no
24
24
  | `owner_login` | `string` | The login of the user or organization that owns the app. |
25
25
  | `owner_node_id` | `string` | The node_id of the user or organization that owns the app. |
26
26
  | `owner_type` | `string` | The type of the owner (e.g., `User`, `Organization`). |
27
+ | `registration_origin` | `string` | Whether the app is tenant-owned, third-party, or unknown. |
27
28
  | `events` | `list[string]` | JSON string of the default webhook events the app subscribes to. |
28
29
  | `installations_count` | `integer` | The total number of installations of this app across all organizations. |
29
30
  | `created_at` | `datetime` | When the app was created. |
30
31
  | `updated_at` | `datetime` | When the app was last updated. |
32
+ | `query_owner` | `string` | Query for the account that registered the app. |
31
33
  | `query_installations` | `string` | Query for installations. |
32
34
 
33
35
  ## Diagram
@@ -36,5 +38,11 @@ App definitions are retrieved via the public `GET /apps/{app_slug}` endpoint (no
36
38
  graph LR
37
39
  n0["GH_App"]
38
40
  n1["GH_AppInstallation"]
41
+ n2["GH_Enterprise"]
42
+ n3["GH_Organization"]
43
+ n4["GH_User"]
39
44
  n0 -->|GH_InstalledAs| n1
45
+ n2 -->|GH_Owns| n0
46
+ n3 -->|GH_Owns| n0
47
+ n4 -->|GH_Owns| n0
40
48
  ```
@@ -0,0 +1,5 @@
1
+ [runtime]
2
+ log_cli_level = "INFO"
3
+
4
+ [destination.bloodhoundenterprise]
5
+ collector_name = "github"
@@ -0,0 +1,12 @@
1
+ [destination.bloodhoundenterprise]
2
+ url = "https://REPLACE_WITH_TENANT.bloodhoundenterprise.io"
3
+ # Credentials for the GitHub OpenHound collector client in BHE.
4
+ token_id = "REPLACE_WITH_BHE_COLLECTOR_TOKEN_ID"
5
+ token_key = "REPLACE_WITH_BHE_COLLECTOR_TOKEN_KEY"
6
+
7
+ [sources.source.github.credentials]
8
+ client_id = "REPLACE_WITH_GITHUB_APP_CLIENT_ID"
9
+ enterprise_name = "REPLACE_WITH_ENTERPRISE_SLUG"
10
+ key_path = "/app/.dlt/github-app.pem"
11
+ # Optional classic PAT for enterprise SAML SSO and SCIM collection:
12
+ # pat_token = "REPLACE_WITH_OPTIONAL_PAT"
@@ -0,0 +1,2 @@
1
+ # Follow published scheduler releases. The -cli image does not poll BHE for jobs.
2
+ OPENHOUND_IMAGE=ghcr.io/specterops/openhound-github:latest
@@ -0,0 +1,150 @@
1
+ # Run the GitHub collector with Docker Compose
2
+
3
+ Run the published GitHub scheduler image against a BloodHound Enterprise (BHE)
4
+ tenant using an enterprise GitHub App. The images support Linux AMD64 and
5
+ ARM64, and Docker automatically selects the image for the host architecture.
6
+
7
+ The scheduler polls BHE for jobs. Starting the container does not start a
8
+ collection: run an on-demand scan or configure a schedule in BHE.
9
+
10
+ ## Prerequisites
11
+
12
+ - Docker Engine with the Compose plugin on Linux, or Docker Desktop on macOS.
13
+ - A BHE tenant with OpenHound enabled and the GitHub extension assets installed.
14
+ - A GitHub OpenHound collector client in BHE and its token ID and token key.
15
+ These are collector-client credentials, not a general user's API token.
16
+ - An enterprise GitHub App installed in the enterprise and the organizations
17
+ you intend to collect, its Client ID, and its private key.
18
+
19
+ See [BHE deployment instructions](https://bloodhound.specterops.io/openhound/deploy-with-compose)
20
+ and [enterprise GitHub App configuration](https://bloodhound.specterops.io/openhound/collectors/github/configure-enterprise-app)
21
+ for collector registration and GitHub permissions. Install the SCIM extension
22
+ if collecting SCIM data. An optional classic PAT with `read:enterprise` enables
23
+ enterprise SAML SSO and SCIM collection; `manage_runners:enterprise` is needed
24
+ only if you also want enterprise self-hosted runner data.
25
+
26
+ ## Prepare configuration
27
+
28
+ From the repository root:
29
+
30
+ ```sh
31
+ cd docker-compose
32
+ cp .env.example .env
33
+ cp .dlt/config.toml.example .dlt/config.toml
34
+ cp .dlt/secrets.toml.example .dlt/secrets.toml
35
+ cp /path/to/downloaded-key.pem .dlt/github-app.pem
36
+ ```
37
+
38
+ The resulting layout is:
39
+
40
+ ```text
41
+ docker-compose/
42
+ ├── compose.yaml
43
+ ├── check_config.py
44
+ ├── .env
45
+ └── .dlt/
46
+ ├── config.toml
47
+ ├── secrets.toml
48
+ └── github-app.pem
49
+ ```
50
+
51
+ Edit `.dlt/secrets.toml` locally and replace the placeholders:
52
+
53
+ | Setting | Value |
54
+ | --- | --- |
55
+ | BHE `url` | Your BHE tenant's HTTPS URL |
56
+ | BHE `token_id`, `token_key` | The GitHub OpenHound collector client's credentials |
57
+ | GitHub `client_id` | The enterprise GitHub App's Client ID |
58
+ | GitHub `enterprise_name` | The slug from `github.com/enterprises/<slug>` |
59
+ | GitHub `key_path` | Leave `/app/.dlt/github-app.pem` when using the layout above |
60
+
61
+ Actual `.env`, `.dlt` configuration files, and private keys are ignored by Git.
62
+ Only the example files are intended for publication. The `.dlt` directory is
63
+ mounted read-only into the container.
64
+
65
+ The container runs as UID/GID `65532` on every host. Its mounted files must be
66
+ readable by that user. On Linux and macOS, keep this host directory owner-only
67
+ while allowing the container to read the mounted copies:
68
+
69
+ ```sh
70
+ chmod 700 .
71
+ chmod 755 .dlt
72
+ chmod 644 .dlt/config.toml .dlt/secrets.toml .dlt/github-app.pem
73
+ ```
74
+
75
+ These commands affect the local key copy, not the original downloaded key. The
76
+ owner-only parent directory protects the host copies while the mounted `.dlt`
77
+ directory and files remain readable inside the container. On Linux systems
78
+ with enforcing SELinux, the bind-mounted `.dlt` directory must also have a
79
+ container-readable SELinux label permitted by the host policy.
80
+
81
+ ## Validate and start
82
+
83
+ ```sh
84
+ docker compose config --quiet
85
+ docker compose pull
86
+ docker compose run --rm --entrypoint python scheduler-github /opt/openhound-check-config.py
87
+ docker compose up -d scheduler-github
88
+ docker compose logs -f scheduler-github
89
+ ```
90
+
91
+ The preflight checks configuration resolution, RSA private-key readability,
92
+ and writable storage. It does not authenticate to GitHub or BHE. The one-shot
93
+ `storage-init` service prepares the named volumes before the scheduler starts;
94
+ the scheduler itself runs as non-root.
95
+
96
+ In BHE, run an on-demand scan for the matching collector client. Follow the
97
+ container logs and BHE's collection, ingest, and analysis status. API rate-limit
98
+ retries can make a large collection take longer.
99
+
100
+ ## Image versions and updates
101
+
102
+ `.env.example` follows the `latest` scheduler release. Set `OPENHOUND_IMAGE` in
103
+ `.env` to a specific published version if you need a fixed deployment. Use the
104
+ scheduler image, without the `-cli` suffix.
105
+
106
+ After changing the image, or to update a deployment using `latest`, run:
107
+
108
+ ```sh
109
+ docker compose pull
110
+ docker compose up -d scheduler-github
111
+ ```
112
+
113
+ A running container does not update automatically when a tag changes in GHCR.
114
+
115
+ ## Storage and operations
116
+
117
+ | Named volume | Contents |
118
+ | --- | --- |
119
+ | `collector-data` | DLT state, the DuckDB lookup database, and application logs under `/var/lib/openhound` |
120
+ | `raw-data` | Raw collection output under `/tmp/openhound` |
121
+
122
+ ```sh
123
+ docker compose ps -a
124
+ docker compose logs --tail 100 scheduler-github
125
+ docker compose stop scheduler-github
126
+ docker compose down
127
+ ```
128
+
129
+ Normal `down` and container recreation preserve the named volumes.
130
+ `docker compose down --volumes` deletes them and their stored collection data.
131
+ Stop the scheduler after a collection completes. Idle shutdown can take up to
132
+ the 30-second polling interval; Compose allows 45 seconds before forcing exit.
133
+
134
+ The collector needs outbound access to GitHub and BHE; no inbound host ports
135
+ are required. Each deployment should have its own BHE collector client and
136
+ Compose project name. Use `docker compose -p <name> ...` consistently if running
137
+ multiple copies so their containers and volumes remain separate.
138
+
139
+ ## Troubleshooting
140
+
141
+ - **Preflight reports a placeholder:** fill in `.dlt/secrets.toml` and rerun it.
142
+ - **Private key or secrets cannot be read:** verify the mounted file paths and
143
+ UID `65532` read permissions. On Linux with enforcing SELinux, also verify
144
+ that policy permits the `.dlt` bind mount. The container key path is
145
+ different from the path of the downloaded key on your host.
146
+ - **BHE authentication fails:** check the tenant URL and the matching GitHub
147
+ OpenHound collector client's token ID/key.
148
+ - **Scheduler is idle:** start an on-demand scan or schedule a collection in BHE.
149
+ - **GitHub authentication fails:** confirm the key belongs to the configured
150
+ app and that the app is installed in the enterprise and target organizations.
@@ -0,0 +1,54 @@
1
+ """Validate local configuration without contacting GitHub or BHE."""
2
+
3
+ import importlib.metadata
4
+ import os
5
+ import tempfile
6
+ from pathlib import Path
7
+ from urllib.parse import urlparse
8
+
9
+ import dlt
10
+ from dlt.common.configuration import resolve_configuration
11
+ from joserfc.jwk import RSAKey
12
+ from openhound_github.source import GithubEnterpriseAppCredentials
13
+
14
+
15
+ def required(name):
16
+ value = dlt.secrets.get(name)
17
+ if value is None or not str(value).strip() or "REPLACE_WITH" in str(value):
18
+ raise ValueError(f"Set {name} in .dlt/secrets.toml")
19
+ return str(value)
20
+
21
+
22
+ url = required("destination.bloodhoundenterprise.url")
23
+ if urlparse(url).scheme != "https" or not urlparse(url).hostname:
24
+ raise ValueError("Set a valid HTTPS BHE tenant URL")
25
+ required("destination.bloodhoundenterprise.token_id")
26
+ required("destination.bloodhoundenterprise.token_key")
27
+ required("sources.source.github.credentials.enterprise_name")
28
+
29
+ credentials = resolve_configuration(
30
+ GithubEnterpriseAppCredentials(),
31
+ sections=("sources", "source", "github", "credentials"),
32
+ )
33
+ issuer = credentials.client_id or credentials.app_id
34
+ if not issuer or "REPLACE_WITH" in str(issuer):
35
+ raise ValueError("Set the GitHub App client_id or app_id")
36
+ key_path = Path(credentials.key_path)
37
+ key = RSAKey.import_key(key_path.read_bytes())
38
+ if not key.is_private:
39
+ raise ValueError("The GitHub App PEM must contain a private key")
40
+
41
+ for directory in (
42
+ Path.cwd(),
43
+ Path(os.environ["DLT_DATA_DIR"]),
44
+ Path(os.environ["PIPELINES_DIR"]),
45
+ Path(os.environ["RUNTIME__LOG_PATH"]),
46
+ Path("/tmp/openhound"),
47
+ ):
48
+ with tempfile.TemporaryFile(mode="w+", dir=directory) as probe:
49
+ probe.write("ok")
50
+
51
+ print("PASS: BHE and enterprise-app configuration resolves; RSA private key is readable.")
52
+ print("PASS: collection, state, lookup, and log directories are writable.")
53
+ print("GitHub collector version:", importlib.metadata.version("openhound-github"))
54
+ print("Preflight does not verify credentials against GitHub or BHE.")
@@ -0,0 +1,62 @@
1
+ name: openhound-github
2
+
3
+ services:
4
+ storage-init:
5
+ image: ${OPENHOUND_IMAGE:-ghcr.io/specterops/openhound-github:latest}
6
+ user: "0:0"
7
+ network_mode: none
8
+ restart: "no"
9
+ entrypoint: ["python", "-c"]
10
+ command:
11
+ - |
12
+ import os
13
+ from pathlib import Path
14
+ for name in ("/var/lib/openhound", "/var/lib/openhound/work", "/var/lib/openhound/dlt", "/var/lib/openhound/dlt/pipelines", "/var/lib/openhound/logs", "/tmp/openhound"):
15
+ path = Path(name)
16
+ path.mkdir(parents=True, exist_ok=True)
17
+ os.chown(path, 65532, 65532)
18
+ print("Collector storage is ready.")
19
+ volumes:
20
+ - collector-data:/var/lib/openhound
21
+ - raw-data:/tmp/openhound
22
+
23
+ scheduler-github:
24
+ image: ${OPENHOUND_IMAGE:-ghcr.io/specterops/openhound-github:latest}
25
+ init: true
26
+ restart: unless-stopped
27
+ stop_grace_period: 45s
28
+ depends_on:
29
+ storage-init:
30
+ condition: service_completed_successfully
31
+ entrypoint: ["python", "/app/src/scheduler.py"]
32
+ working_dir: /var/lib/openhound/work
33
+ environment:
34
+ DLT_PROJECT_DIR: /app
35
+ DLT_DATA_DIR: /var/lib/openhound/dlt
36
+ PIPELINES_DIR: /var/lib/openhound/dlt/pipelines
37
+ RUNTIME__LOG_PATH: /var/lib/openhound/logs
38
+ DESTINATION__BLOODHOUNDENTERPRISE__COLLECTOR_NAME: github
39
+ volumes:
40
+ - type: bind
41
+ source: ./.dlt
42
+ target: /app/.dlt
43
+ read_only: true
44
+ bind:
45
+ create_host_path: false
46
+ - type: bind
47
+ source: ./check_config.py
48
+ target: /opt/openhound-check-config.py
49
+ read_only: true
50
+ bind:
51
+ create_host_path: false
52
+ - collector-data:/var/lib/openhound
53
+ - raw-data:/tmp/openhound
54
+ logging:
55
+ driver: json-file
56
+ options:
57
+ max-size: "10m"
58
+ max-file: "3"
59
+
60
+ volumes:
61
+ collector-data:
62
+ raw-data:
@@ -2121,7 +2121,7 @@
2121
2121
  },
2122
2122
  {
2123
2123
  "name": "GH_Owns",
2124
- "description": "Organization owns a repository",
2124
+ "description": "GitHub account owns an application or repository",
2125
2125
  "is_traversable": true
2126
2126
  },
2127
2127
  {
@@ -118,6 +118,38 @@ class GithubLookup(LookupManager):
118
118
  [enterprise_node_id],
119
119
  )
120
120
 
121
+ @lru_cache
122
+ def is_tenant_organization_node_id(self, node_id: str) -> bool:
123
+ """Return whether an organization belongs to the collected tenant."""
124
+ collected_org_id = self._find_single_object(
125
+ f"""SELECT node_id FROM {self.schema}.organizations WHERE node_id = ?""",
126
+ [node_id],
127
+ )
128
+ if collected_org_id is not None:
129
+ return True
130
+
131
+ enterprise_org_id = self._find_single_object(
132
+ f"""SELECT id FROM {self.schema}.enterprise_organizations WHERE id = ?""",
133
+ [node_id],
134
+ )
135
+ return enterprise_org_id is not None
136
+
137
+ @lru_cache
138
+ def is_collected_user_node_id(self, node_id: str) -> bool:
139
+ """Return whether a user node exists in collected organization or enterprise data."""
140
+ organization_user_id = self._find_single_object(
141
+ f"""SELECT id FROM {self.schema}.users WHERE id = ?""",
142
+ [node_id],
143
+ )
144
+ if organization_user_id is not None:
145
+ return True
146
+
147
+ enterprise_user_id = self._find_single_object(
148
+ f"""SELECT id FROM {self.schema}.enterprise_users WHERE id = ?""",
149
+ [node_id],
150
+ )
151
+ return enterprise_user_id is not None
152
+
121
153
  @lru_cache
122
154
  def _enterprise_runner_group_identity_for_inherited_org_group(
123
155
  self, org_node_id: str, group_name: str
@@ -215,10 +215,12 @@ class GHAppProperties(GHNodeProperties):
215
215
  owner_login: The login of the user or organization that owns the app.
216
216
  owner_node_id: The node_id of the user or organization that owns the app.
217
217
  owner_type: The type of the owner (e.g., `User`, `Organization`).
218
+ registration_origin: Whether the app is tenant-owned, third-party, or unknown.
218
219
  events: JSON string of the default webhook events the app subscribes to.
219
220
  installations_count: The total number of installations of this app across all organizations.
220
221
  created_at: When the app was created.
221
222
  updated_at: When the app was last updated.
223
+ query_owner: Query for the account that registered the app.
222
224
  query_installations: Query for installations.
223
225
  """
224
226
 
@@ -231,10 +233,12 @@ class GHAppProperties(GHNodeProperties):
231
233
  owner_login: str | None = None
232
234
  owner_node_id: str | None = None
233
235
  owner_type: str | None = None
236
+ registration_origin: str | None = None
234
237
  events: list[str] | None = None
235
238
  installations_count: int | None = None
236
239
  created_at: datetime | None = None
237
240
  updated_at: datetime | None = None
241
+ query_owner: str | None = None
238
242
  query_installations: str | None = None
239
243
 
240
244
 
@@ -252,6 +256,29 @@ class Owner(BaseModel):
252
256
  icon="cube",
253
257
  properties=GHAppProperties,
254
258
  ),
259
+ edges=[
260
+ EdgeDef(
261
+ start=nk.ENTERPRISE,
262
+ end=nk.APP,
263
+ kind=ek.OWNS,
264
+ description="Enterprise owns GitHub App",
265
+ traversable=True,
266
+ ),
267
+ EdgeDef(
268
+ start=nk.ORGANIZATION,
269
+ end=nk.APP,
270
+ kind=ek.OWNS,
271
+ description="Organization owns GitHub App",
272
+ traversable=True,
273
+ ),
274
+ EdgeDef(
275
+ start=nk.USER,
276
+ end=nk.APP,
277
+ kind=ek.OWNS,
278
+ description="User owns GitHub App",
279
+ traversable=True,
280
+ ),
281
+ ],
255
282
  )
256
283
  class App(BaseAsset):
257
284
  """One record from `apps` → one GH_App node. Edges (GH_InstalledAs) are emitted by AppInstallationAsset."""
@@ -262,7 +289,7 @@ class App(BaseAsset):
262
289
  slug: str
263
290
  client_id: str | None = None
264
291
  node_id: str
265
- owner: Owner
292
+ owner: Owner | None = None
266
293
  name: str
267
294
  description: str | None = None
268
295
  permissions: dict
@@ -282,6 +309,51 @@ class App(BaseAsset):
282
309
  return self.collected_org_node_id
283
310
  return self._lookup.org_id_for_login(self.org_login)
284
311
 
312
+ @property
313
+ def registration_origin(self) -> str:
314
+ if self.owner is None:
315
+ return "unknown"
316
+
317
+ owner_type = self.owner.type.casefold()
318
+ if owner_type == "user":
319
+ return "third_party"
320
+
321
+ if owner_type == "organization":
322
+ if self._lookup.is_tenant_organization_node_id(self.owner.node_id):
323
+ return "tenant_owned"
324
+ return "third_party" if self._lookup.enterprise_id() else "unknown"
325
+
326
+ if owner_type == "enterprise":
327
+ enterprise_id = self._lookup.enterprise_id()
328
+ if enterprise_id is None:
329
+ return "unknown"
330
+ return (
331
+ "tenant_owned"
332
+ if self.owner.node_id == enterprise_id
333
+ else "third_party"
334
+ )
335
+
336
+ return "unknown"
337
+
338
+ @property
339
+ def registration_owner_node_id(self) -> str | None:
340
+ if self.owner is None:
341
+ return None
342
+
343
+ owner_type = self.owner.type.casefold()
344
+ if owner_type == "organization":
345
+ owner_exists = self._lookup.is_tenant_organization_node_id(
346
+ self.owner.node_id
347
+ )
348
+ elif owner_type == "enterprise":
349
+ owner_exists = self._lookup.enterprise_id() == self.owner.node_id
350
+ elif owner_type == "user":
351
+ owner_exists = self._lookup.is_collected_user_node_id(self.owner.node_id)
352
+ else:
353
+ owner_exists = False
354
+
355
+ return self.owner.node_id if owner_exists else None
356
+
285
357
  @property
286
358
  def as_node(self):
287
359
  aid = self.node_id
@@ -298,21 +370,34 @@ class App(BaseAsset):
298
370
  description=self.description,
299
371
  external_url=self.external_url,
300
372
  html_url=self.html_url,
301
- # owner_login=self.owner_login,
302
- # owner_node_id=self.owner_node_id,
303
- # owner_type=self.owner_type,
373
+ owner_login=self.owner.login if self.owner else None,
374
+ owner_node_id=self.owner.node_id if self.owner else None,
375
+ owner_type=self.owner.type if self.owner else None,
376
+ registration_origin=self.registration_origin,
304
377
  # permissions=self.permissions,
305
378
  # installations_count=self.installations_count,
306
379
  events=self.events,
307
380
  created_at=self.created_at,
308
381
  updated_at=self.updated_at,
382
+ query_owner=f"MATCH p=(owner)-[:GH_Owns]->(:GH_App {{node_id:'{aid}'}}) RETURN p",
309
383
  query_installations=f"MATCH p=(:GH_App {{node_id:'{aid}'}})-[:GH_InstalledAs]->(:GH_AppInstallation) RETURN p",
310
384
  ),
311
385
  )
312
386
 
313
387
  @property
314
388
  def edges(self) -> list[Edge]:
315
- return []
389
+ owner_node_id = self.registration_owner_node_id
390
+ if owner_node_id is None:
391
+ return []
392
+
393
+ return [
394
+ Edge(
395
+ kind=ek.OWNS,
396
+ start=EdgePath(value=owner_node_id, match_by="id"),
397
+ end=EdgePath(value=self.node_id, match_by="id"),
398
+ properties=EdgeProperties(traversable=True),
399
+ )
400
+ ]
316
401
 
317
402
 
318
403
  @app.asset(