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.
- {openhound_github-0.21.2 → openhound_github-0.22.0}/.github/workflows/publish-container.yml +28 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/.gitignore +5 -0
- openhound_github-0.21.2/README.md → openhound_github-0.22.0/PKG-INFO +20 -1
- openhound_github-0.21.2/PKG-INFO → openhound_github-0.22.0/README.md +9 -12
- openhound_github-0.22.0/descriptions/edges/GH_Owns.md +29 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_App.md +8 -0
- openhound_github-0.22.0/docker-compose/.dlt/config.toml.example +5 -0
- openhound_github-0.22.0/docker-compose/.dlt/secrets.toml.example +12 -0
- openhound_github-0.22.0/docker-compose/.env.example +2 -0
- openhound_github-0.22.0/docker-compose/README.md +150 -0
- openhound_github-0.22.0/docker-compose/check_config.py +54 -0
- openhound_github-0.22.0/docker-compose/compose.yaml +62 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/schema.json +1 -1
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/lookup.py +32 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/app_installation.py +90 -5
- openhound_github-0.22.0/tests/test_app_model.py +121 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_lookup.py +38 -0
- openhound_github-0.21.2/descriptions/edges/GH_Owns.md +0 -20
- {openhound_github-0.21.2 → openhound_github-0.22.0}/.dockerignore +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/.github/CODE_OF_CONDUCT.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/.github/CONTRIBUTING.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/.github/GOVERNANCE.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/.github/SECURITY.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/.github/SO-Dark.svg +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/.github/SO-FOSS-Dark.svg +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/.github/SO-FOSS-Light.svg +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/.github/SO-Light.svg +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/.github/workflows/publish.yml +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/.github/workflows/release-on-merge.yml +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/.github/workflows/validate-branch.yml +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/.pre-commit-config.yaml +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/Dockerfile +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/LICENSE.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_AddAssignee.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_AddCollaborator.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_AddLabel.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_AddMember.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_AddedDeployKey.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_AdminTo.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ApprovesDeploymentTo.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_AssignedTo.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_AuthorizedForOrganization.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_BypassBranchProtection.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_BypassPullRequestAllowances.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CallsWorkflow.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanAccess.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanAccessSecret.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanAssumeIdentity.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanCreateBranch.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanCreateEnvironment.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanCreateInternalRepositories.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanCreatePrivateRepositories.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanCreatePublicRepositories.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanCreateRepositories.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanCreateRepositoryWithRunnerAccess.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanDeployToEnvironment.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanEditEnvironment.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanEditProtection.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanInterceptJob.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanPwnRequest.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanReadSecret.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanReadSecretScanningAlert.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanRequestOIDCTokenFor.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanUseRunner.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CanWriteBranch.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CloseDiscussion.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CloseIssue.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ClosePullRequest.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_Contains.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ConvertIssuesToDiscussions.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CreateDiscussionCategory.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CreateEnterpriseOrganizations.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CreateRepository.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CreateSoloMergeQueueEntry.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CreateTag.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_CreateTeam.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_DeleteAlertsCodeScanning.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_DeleteDiscussion.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_DeleteDiscussionComment.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_DeleteIssue.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_DeleteTag.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_DependsOn.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_DeploysTo.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_EditCategoryOnDiscussion.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_EditDiscussionCategory.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_EditDiscussionComment.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_EditEnterpriseCustomPropertiesForOrganizations.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_EditRepoAnnouncementBanners.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_EditRepoCustomPropertiesValues.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_EditRepoMetadata.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_EditRepoProtections.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_HasBaseRole.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_HasExternalIdentity.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_HasMember.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_HasPersonalAccessToken.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_HasPersonalAccessTokenRequest.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_HasRole.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_HasRunner.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_HasSamlIdentityProvider.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_HasSecret.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_HasVariable.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_InheritedFrom.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_InstalledAs.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_InviteMember.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_IsEligibleFor.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_JumpMergeQueue.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageDeployKeys.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageDiscussionBadges.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageEnterpriseAdmins.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageEnterpriseIdentityProvider.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageEnterpriseMembers.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageEnterpriseOrganizationAdmins.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageEnterpriseOrganizations.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageEnterpriseReferrals.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageEnterpriseTeams.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageOrganizationWebhooks.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageRepoSecurityProducts.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageSecurityProducts.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageSettingsMergeTypes.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageSettingsPages.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageSettingsProjects.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageSettingsWiki.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageTopics.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ManageWebhooks.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_MapsToUser.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_MarkAsDuplicate.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_MatchesEnvironmentPolicy.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_MemberOf.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_OrgBypassCodeScanningDismissalRequests.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_OrgBypassSecretScanningClosureRequests.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_OrgReviewAndManageSecretScanningBypassRequests.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_OrgReviewAndManageSecretScanningClosureRequests.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ProtectedBy.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_PushProtectedBranch.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ReadCodeScanning.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ReadEnterpriseAuditLog.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ReadEnterpriseDomainVerification.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ReadEnterpriseMembers.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ReadEnterpriseOrgProjects.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ReadEnterpriseOrganizationAdmin.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ReadOrganizationActionsUsageMetrics.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ReadOrganizationCustomOrgRole.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ReadOrganizationCustomRepoRole.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ReadRepoContents.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_RemoveAssignee.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_RemoveLabel.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ReopenDiscussion.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ReopenIssue.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ReopenPullRequest.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_RequestPrReview.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_RequestsAccessTo.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ResolveDependabotAlerts.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ResolveSecretScanningAlerts.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_RestrictionsCanPush.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_RunOrgMigration.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_RunsOn.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ScopedTo.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_SetEnterpriseInteractionLimits.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_SetInteractionLimits.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_SetIssueType.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_SetMilestone.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_SetSocialPreview.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_SyncedTo.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ToggleDiscussionAnswer.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ToggleDiscussionCommentMinimize.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_TransferRepository.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_UsesSecret.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_UsesVariable.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ValidToken.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ViewDependabotAlerts.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ViewEnterpriseActionsUsageMetrics.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ViewEnterpriseBilling.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ViewEnterpriseSecretScanningAlerts.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_ViewSecretScanningAlerts.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_WriteCodeScanning.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_WriteEnterpriseActionsPolicies.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_WriteEnterpriseBilling.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_WriteEnterprisePersonalAccessTokenPolicies.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_WriteEnterpriseSso.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_WriteEnterpriseTeamMembers.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_WriteOrganizationActionsSecrets.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_WriteOrganizationActionsSettings.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_WriteOrganizationActionsVariables.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_WriteOrganizationCustomOrgRole.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_WriteOrganizationCustomRepoRole.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_WriteOrganizationNetworkConfigurations.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_WriteRepoContents.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/edges/GH_WriteRepoPullRequests.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_AppInstallation.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_Branch.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_BranchProtectionRule.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_ClassicPersonalAccessToken.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_DeployKey.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_Enterprise.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_EnterpriseManagedUser.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_EnterpriseRole.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_EnterpriseRunner.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_EnterpriseRunnerGroup.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_EnterpriseTeam.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_Environment.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_EnvironmentBranchPolicy.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_EnvironmentSecret.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_EnvironmentVariable.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_ExternalIdentity.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_OrgRole.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_OrgRunner.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_OrgRunnerGroup.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_OrgSecret.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_OrgVariable.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_Organization.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_PersonalAccessToken.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_PersonalAccessTokenRequest.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_RepoRole.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_RepoRunner.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_RepoSecret.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_RepoVariable.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_Repository.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_Runner.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_RunnerGroup.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_SamlIdentityProvider.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_Scope.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_Secret.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_SecretScanningAlert.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_Team.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_TeamRole.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_User.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_Variable.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_Workflow.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_WorkflowJob.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/descriptions/nodes/GH_WorkflowStep.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/privilege_zone_rules/t0-all-repo-admin-role.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/privilege_zone_rules/t0-app-installations-all-repos.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/privilege_zone_rules/t0-apps-all-repos.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/privilege_zone_rules/t0-enterprise-owners-role.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/privilege_zone_rules/t0-external-identities-owners.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/privilege_zone_rules/t0-organizations.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/privilege_zone_rules/t0-owner-users.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/privilege_zone_rules/t0-owners-role.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/privilege_zone_rules/t0-pats-all-repos.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/privilege_zone_rules/t0-privilege-escalation-roles.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/privilege_zone_rules/t0-privilege-escalation-users.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/privilege_zone_rules/t0-saml-identity-providers.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/README.md +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/actions-sha-pinning-not-required.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/active-leaked-secrets.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/advanced-security-disabled-new-repos.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/all-actions-allowed.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/app-installations-all-repos.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/branch-protection-admins-not-enforced.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/branch-protection-deletions-allowed.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/branch-protection-force-pushes.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/branch-protection-no-code-owner-reviews.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/branch-protection-no-pr-reviews.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/branch-protection-no-status-checks.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/branch-protection-self-approval.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/branch-protection-stale-reviews.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/bypass-pr-requirements.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/dangerous-branch-perms.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/default-repository-permissions.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/demo-sso-to-cloud-round-trip.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/dependabot-alerts-disabled-new-repos.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/dependabot-updates-disabled-new-repos.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/dependency-graph-disabled-new-repos.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/environments-admin-bypass.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/expired-pats.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/external-identities-without-scim.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/github-to-azure-identity.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/global-repo-perms.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/hybrid-identities.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/members-can-change-repo-visibility.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/members-can-create-pages.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/members-can-create-public-repos.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/members-can-delete-repos.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/members-can-fork-private-repos.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/members-can-invite-outside-collaborators.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/org-owners.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/orgs-without-2fa.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/pats-all-repo-access.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/pending-pat-requests.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/private-repos-forking-allowed.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/privileged-custom-org-roles.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/privileged-hybrid-identities.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/public-repos.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/push-protection-disabled-new-repos.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/push-to-protected-branches.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/repos-secret-scanning-disabled.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/repos-vulnerable-to-workflow-secret-exfil.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/repository-workflows.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/saml-configuration.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/secret-scanning-alerts.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/secret-scanning-disabled-new-repos.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/secrets-reachable-by-user.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/self-hosted-runners-can-intercept-broad-token-jobs.json +0 -0
- {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
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/team-membership-admin.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/team-structure.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/unprotected-branches.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/unprotected-default-branch-with-workflow.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/unprotected-default-branches.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/web-commit-signoff-not-required.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/workflow-jobs-interceptable-by-self-hosted-runners.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/workflow-jobs-with-broad-token-write-permissions.json +0 -0
- {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
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/workflow-jobs-with-id-token-write.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/extension/saved_searches/workflow-jobs-with-observed-oidc-auth-steps.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/justfile +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/pyproject.toml +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/scripts/generate_gh_description_docs.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/main.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/__init__.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/auth.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/extension.yaml +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/github_rest_client.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/github_retry.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/graph.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/graphql.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/helpers.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/kinds/edges.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/kinds/nodes.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/main.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/__init__.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/actions_permission.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/branch.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/branch_pr_bypass_allowance.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/branch_protection_rule.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/branch_push_allowance.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/classic_personal_access_token.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/deploy_key.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise_admin.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise_credential_inventory.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise_helpers.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise_managed_user.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise_member.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise_organization.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise_role.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise_role_team.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise_role_user.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise_team.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise_team_member.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise_team_organization.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise_team_role.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/enterprise_user.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/env_secret.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/env_variable.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/environment.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/environment_branch_policy.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/external_identity.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/org.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/org_role.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/org_role_member.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/org_role_team.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/org_secret.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/org_variable.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/permissions.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/personal_access_token.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/personal_access_token_access.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/personal_access_token_request.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/projected_enterprise_team.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/repo_role_assignment.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/repository.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/repository_role.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/repository_secret.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/repository_variable.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/runner.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/saml_assertion_consumer_service.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/saml_helpers.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/saml_issuer.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/saml_provider.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/saml_service_provider.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/scim_user.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/scope.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/secret_scanning_alert.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/team.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/team_member.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/team_role.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/user.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/workflow.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/workflow_job.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/workflow_reference.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/workflow_step.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/resources/__init__.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/resources/enterprise.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/resources/organization.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/runner_ids.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/source.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/transforms.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/src/scheduler.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_app_auth.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_app_installation_repo_access.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_branch_collection_gate.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_branch_protection_traversability.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_classic_personal_access_tokens.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_credential_permission_models.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/actions-permissions.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/actionsecrets.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/app.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/appinstalls.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/branch-policies.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/branch-prot-rules.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/branches.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/custom-roles.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/environments.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/org-pat-request.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/org-pat.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/org-role-teams.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/org-role-users.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/org-roles.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/org.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/pat-repositories.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/repo-collaborators.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/repo-teams.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/repositories.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/scimusers.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/secrets.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/secretscanningalert.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/selected-org-secrets.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/variables.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_data/api/workflows.json +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_deploy_key_models.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_deploy_key_resources.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_description_docs.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_enterprise_capabilities.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_enterprise_organization.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_enterprise_resources.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_environment_model.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_environment_resources.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_environment_reviewer_lookup.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_error_resilience.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_github_app_retry.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_github_rest_client.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_github_retry.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_helpers.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_org_role_model.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_org_scim_resources.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_org_secret_models.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_preproc.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_repository_rulesets.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_repository_scopes.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_runner_ids.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_runner_models.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_runner_resources.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_saml_helpers.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_saml_models.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_scim_models.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_source_endpoints.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_source_org_canonicalization.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_team_external_groups.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_variable_models.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_workflow_interception_path.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_workflow_model.py +0 -0
- {openhound_github-0.21.2 → openhound_github-0.22.0}/tests/test_workflow_resources.py +0 -0
- {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.
|
|
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.
|
|
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,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,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:
|
|
@@ -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
|
{openhound_github-0.21.2 → openhound_github-0.22.0}/src/openhound_github/models/app_installation.py
RENAMED
|
@@ -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
|
-
|
|
302
|
-
|
|
303
|
-
|
|
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
|
-
|
|
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(
|