openhound-github 0.20.1__tar.gz → 0.21.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.0/.dockerignore +15 -0
- openhound_github-0.21.0/.github/workflows/publish-container.yml +128 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/.github/workflows/publish.yml +18 -1
- {openhound_github-0.20.1 → openhound_github-0.21.0}/.github/workflows/release-on-merge.yml +16 -2
- openhound_github-0.21.0/Dockerfile +35 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/PKG-INFO +76 -1
- {openhound_github-0.20.1 → openhound_github-0.21.0}/README.md +75 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/pyproject.toml +3 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/__init__.py +2 -0
- openhound_github-0.21.0/src/openhound_github/models/enterprise_credential_inventory.py +19 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/resources/enterprise.py +2 -1
- openhound_github-0.21.0/src/scheduler.py +25 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_classic_personal_access_tokens.py +42 -2
- {openhound_github-0.20.1 → openhound_github-0.21.0}/uv.lock +6 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/.github/CODE_OF_CONDUCT.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/.github/CONTRIBUTING.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/.github/GOVERNANCE.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/.github/SECURITY.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/.github/SO-Dark.svg +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/.github/SO-FOSS-Dark.svg +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/.github/SO-FOSS-Light.svg +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/.github/SO-Light.svg +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/.github/workflows/validate-branch.yml +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/.gitignore +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/.gitmodules +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/.pre-commit-config.yaml +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/LICENSE.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_AddAssignee.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_AddCollaborator.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_AddLabel.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_AddMember.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_AddedDeployKey.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_AdminTo.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ApprovesDeploymentTo.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_AssignedTo.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_AuthorizedForOrganization.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_BypassBranchProtection.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_BypassPullRequestAllowances.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_CallsWorkflow.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_CanAccess.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_CanAccessSecret.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_CanAssumeIdentity.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_CanCreateBranch.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_CanCreateEnvironment.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_CanCreateInternalRepositories.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_CanCreatePrivateRepositories.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_CanCreatePublicRepositories.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_CanCreateRepositories.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_CanCreateRepositoryWithRunnerAccess.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_CanDeployToEnvironment.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_CanEditEnvironment.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_CanEditProtection.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_CanInterceptJob.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_CanPwnRequest.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_CanReadSecret.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_CanReadSecretScanningAlert.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_CanRequestOIDCTokenFor.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_CanUseRunner.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_CanWriteBranch.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_CloseDiscussion.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_CloseIssue.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ClosePullRequest.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_Contains.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ConvertIssuesToDiscussions.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_CreateDiscussionCategory.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_CreateEnterpriseOrganizations.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_CreateRepository.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_CreateSoloMergeQueueEntry.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_CreateTag.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_CreateTeam.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_DeleteAlertsCodeScanning.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_DeleteDiscussion.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_DeleteDiscussionComment.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_DeleteIssue.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_DeleteTag.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_DependsOn.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_DeploysTo.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_EditCategoryOnDiscussion.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_EditDiscussionCategory.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_EditDiscussionComment.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_EditEnterpriseCustomPropertiesForOrganizations.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_EditRepoAnnouncementBanners.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_EditRepoCustomPropertiesValues.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_EditRepoMetadata.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_EditRepoProtections.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_HasBaseRole.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_HasExternalIdentity.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_HasMember.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_HasPersonalAccessToken.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_HasPersonalAccessTokenRequest.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_HasRole.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_HasRunner.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_HasSamlIdentityProvider.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_HasSecret.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_HasVariable.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_InheritedFrom.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_InstalledAs.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_InviteMember.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_IsEligibleFor.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_JumpMergeQueue.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ManageDeployKeys.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ManageDiscussionBadges.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ManageEnterpriseAdmins.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ManageEnterpriseIdentityProvider.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ManageEnterpriseMembers.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ManageEnterpriseOrganizationAdmins.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ManageEnterpriseOrganizations.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ManageEnterpriseReferrals.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ManageEnterpriseTeams.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ManageOrganizationWebhooks.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ManageRepoSecurityProducts.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ManageSecurityProducts.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ManageSettingsMergeTypes.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ManageSettingsPages.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ManageSettingsProjects.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ManageSettingsWiki.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ManageTopics.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ManageWebhooks.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_MapsToUser.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_MarkAsDuplicate.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_MatchesEnvironmentPolicy.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_MemberOf.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_OrgBypassCodeScanningDismissalRequests.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_OrgBypassSecretScanningClosureRequests.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_OrgReviewAndManageSecretScanningBypassRequests.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_OrgReviewAndManageSecretScanningClosureRequests.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_Owns.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ProtectedBy.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_PushProtectedBranch.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ReadCodeScanning.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ReadEnterpriseAuditLog.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ReadEnterpriseDomainVerification.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ReadEnterpriseMembers.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ReadEnterpriseOrgProjects.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ReadEnterpriseOrganizationAdmin.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ReadOrganizationActionsUsageMetrics.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ReadOrganizationCustomOrgRole.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ReadOrganizationCustomRepoRole.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ReadRepoContents.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_RemoveAssignee.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_RemoveLabel.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ReopenDiscussion.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ReopenIssue.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ReopenPullRequest.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_RequestPrReview.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_RequestsAccessTo.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ResolveDependabotAlerts.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ResolveSecretScanningAlerts.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_RestrictionsCanPush.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_RunOrgMigration.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_RunsOn.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ScopedTo.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_SetEnterpriseInteractionLimits.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_SetInteractionLimits.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_SetIssueType.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_SetMilestone.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_SetSocialPreview.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_SyncedTo.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ToggleDiscussionAnswer.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ToggleDiscussionCommentMinimize.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_TransferRepository.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_UsesSecret.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_UsesVariable.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ValidToken.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ViewDependabotAlerts.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ViewEnterpriseActionsUsageMetrics.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ViewEnterpriseBilling.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ViewEnterpriseSecretScanningAlerts.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_ViewSecretScanningAlerts.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_WriteCodeScanning.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_WriteEnterpriseActionsPolicies.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_WriteEnterpriseBilling.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_WriteEnterprisePersonalAccessTokenPolicies.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_WriteEnterpriseSso.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_WriteEnterpriseTeamMembers.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_WriteOrganizationActionsSecrets.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_WriteOrganizationActionsSettings.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_WriteOrganizationActionsVariables.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_WriteOrganizationCustomOrgRole.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_WriteOrganizationCustomRepoRole.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_WriteOrganizationNetworkConfigurations.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_WriteRepoContents.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_WriteRepoPullRequests.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_App.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_AppInstallation.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_Branch.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_BranchProtectionRule.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_ClassicPersonalAccessToken.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_DeployKey.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_Enterprise.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_EnterpriseManagedUser.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_EnterpriseRole.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_EnterpriseRunner.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_EnterpriseRunnerGroup.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_EnterpriseTeam.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_Environment.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_EnvironmentBranchPolicy.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_EnvironmentSecret.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_EnvironmentVariable.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_ExternalIdentity.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_OrgRole.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_OrgRunner.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_OrgRunnerGroup.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_OrgSecret.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_OrgVariable.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_Organization.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_PersonalAccessToken.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_PersonalAccessTokenRequest.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_RepoRole.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_RepoRunner.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_RepoSecret.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_RepoVariable.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_Repository.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_Runner.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_RunnerGroup.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_SamlIdentityProvider.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_Scope.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_Secret.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_SecretScanningAlert.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_Team.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_TeamRole.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_User.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_Variable.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_Workflow.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_WorkflowJob.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/nodes/GH_WorkflowStep.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/docs/og-docs.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/privilege_zone_rules/t0-all-repo-admin-role.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/privilege_zone_rules/t0-app-installations-all-repos.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/privilege_zone_rules/t0-apps-all-repos.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/privilege_zone_rules/t0-enterprise-owners-role.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/privilege_zone_rules/t0-external-identities-owners.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/privilege_zone_rules/t0-organizations.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/privilege_zone_rules/t0-owner-users.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/privilege_zone_rules/t0-owners-role.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/privilege_zone_rules/t0-pats-all-repos.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/privilege_zone_rules/t0-privilege-escalation-roles.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/privilege_zone_rules/t0-privilege-escalation-users.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/privilege_zone_rules/t0-saml-identity-providers.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/README.md +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/actions-sha-pinning-not-required.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/active-leaked-secrets.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/advanced-security-disabled-new-repos.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/all-actions-allowed.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/app-installations-all-repos.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/branch-protection-admins-not-enforced.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/branch-protection-deletions-allowed.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/branch-protection-force-pushes.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/branch-protection-no-code-owner-reviews.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/branch-protection-no-pr-reviews.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/branch-protection-no-status-checks.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/branch-protection-self-approval.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/branch-protection-stale-reviews.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/bypass-pr-requirements.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/dangerous-branch-perms.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/default-repository-permissions.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/demo-sso-to-cloud-round-trip.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/dependabot-alerts-disabled-new-repos.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/dependabot-updates-disabled-new-repos.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/dependency-graph-disabled-new-repos.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/environments-admin-bypass.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/expired-pats.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/external-identities-without-scim.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/github-to-azure-identity.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/global-repo-perms.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/hybrid-identities.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/members-can-change-repo-visibility.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/members-can-create-pages.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/members-can-create-public-repos.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/members-can-delete-repos.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/members-can-fork-private-repos.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/members-can-invite-outside-collaborators.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/org-owners.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/orgs-without-2fa.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/pats-all-repo-access.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/pending-pat-requests.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/private-repos-forking-allowed.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/privileged-custom-org-roles.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/privileged-hybrid-identities.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/public-repos.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/push-protection-disabled-new-repos.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/push-to-protected-branches.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/repos-secret-scanning-disabled.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/repos-vulnerable-to-workflow-secret-exfil.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/repository-workflows.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/saml-configuration.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/secret-scanning-alerts.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/secret-scanning-disabled-new-repos.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/secrets-reachable-by-user.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/self-hosted-runners-can-intercept-broad-token-jobs.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/shared-self-hosted-runners-can-intercept-secret-bearing-jobs.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/team-membership-admin.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/team-structure.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/unprotected-branches.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/unprotected-default-branch-with-workflow.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/unprotected-default-branches.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/web-commit-signoff-not-required.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/workflow-jobs-interceptable-by-self-hosted-runners.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/workflow-jobs-with-broad-token-write-permissions.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/workflow-jobs-with-id-token-write-on-self-hosted-runners.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/workflow-jobs-with-id-token-write.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/saved_searches/workflow-jobs-with-observed-oidc-auth-steps.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/extension/schema.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/justfile +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/scripts/generate_gh_description_docs.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/main.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/__init__.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/auth.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/extension.yaml +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/github_rest_client.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/github_retry.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/graph.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/graphql.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/helpers.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/kinds/edges.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/kinds/nodes.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/lookup.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/main.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/actions_permission.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/app_installation.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/branch.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/branch_pr_bypass_allowance.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/branch_protection_rule.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/branch_push_allowance.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/classic_personal_access_token.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/deploy_key.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/enterprise.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/enterprise_admin.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/enterprise_helpers.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/enterprise_managed_user.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/enterprise_member.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/enterprise_organization.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/enterprise_role.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/enterprise_role_team.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/enterprise_role_user.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/enterprise_team.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/enterprise_team_member.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/enterprise_team_organization.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/enterprise_team_role.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/enterprise_user.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/env_secret.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/env_variable.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/environment.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/environment_branch_policy.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/external_identity.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/org.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/org_role.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/org_role_member.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/org_role_team.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/org_secret.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/org_variable.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/permissions.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/personal_access_token.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/personal_access_token_access.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/personal_access_token_request.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/projected_enterprise_team.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/repo_role_assignment.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/repository.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/repository_role.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/repository_secret.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/repository_variable.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/runner.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/saml_assertion_consumer_service.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/saml_helpers.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/saml_issuer.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/saml_provider.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/saml_service_provider.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/scim_user.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/scope.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/secret_scanning_alert.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/team.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/team_member.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/team_role.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/user.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/workflow.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/workflow_job.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/workflow_reference.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/models/workflow_step.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/resources/__init__.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/resources/organization.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/runner_ids.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/source.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/transforms.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_app_auth.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_app_installation_repo_access.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_branch_collection_gate.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_branch_protection_traversability.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_credential_permission_models.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_data/api/actions-permissions.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_data/api/actionsecrets.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_data/api/app.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_data/api/appinstalls.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_data/api/branch-policies.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_data/api/branch-prot-rules.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_data/api/branches.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_data/api/custom-roles.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_data/api/environments.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_data/api/org-pat-request.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_data/api/org-pat.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_data/api/org-role-teams.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_data/api/org-role-users.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_data/api/org-roles.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_data/api/org.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_data/api/pat-repositories.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_data/api/repo-collaborators.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_data/api/repo-teams.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_data/api/repositories.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_data/api/scimusers.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_data/api/secrets.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_data/api/secretscanningalert.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_data/api/selected-org-secrets.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_data/api/variables.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_data/api/workflows.json +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_deploy_key_models.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_deploy_key_resources.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_description_docs.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_enterprise_capabilities.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_enterprise_organization.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_enterprise_resources.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_environment_model.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_environment_resources.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_environment_reviewer_lookup.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_error_resilience.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_github_app_retry.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_github_rest_client.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_github_retry.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_helpers.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_lookup.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_org_role_model.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_org_scim_resources.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_org_secret_models.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_preproc.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_repository_rulesets.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_repository_scopes.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_runner_ids.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_runner_models.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_runner_resources.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_saml_helpers.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_saml_models.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_scim_models.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_source_endpoints.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_source_org_canonicalization.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_team_external_groups.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_variable_models.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_workflow_interception_path.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_workflow_model.py +0 -0
- {openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_workflow_resources.py +0 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
name: Build and publish container
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_call:
|
|
5
|
+
inputs:
|
|
6
|
+
tag:
|
|
7
|
+
description: Existing release tag to build
|
|
8
|
+
required: true
|
|
9
|
+
type: string
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
packages: write
|
|
14
|
+
|
|
15
|
+
concurrency:
|
|
16
|
+
group: container-${{ inputs.tag }}
|
|
17
|
+
cancel-in-progress: false
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
publish:
|
|
21
|
+
if: >-
|
|
22
|
+
github.repository == 'SpecterOps/openhound-github' &&
|
|
23
|
+
github.event_name == 'pull_request' &&
|
|
24
|
+
github.event.action == 'closed' &&
|
|
25
|
+
github.event.pull_request.merged == true &&
|
|
26
|
+
github.event.pull_request.base.ref == 'main'
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
strategy:
|
|
29
|
+
matrix:
|
|
30
|
+
target: [cli, enterprise]
|
|
31
|
+
steps:
|
|
32
|
+
- name: Validate release tag
|
|
33
|
+
env:
|
|
34
|
+
RELEASE_TAG: ${{ inputs.tag }}
|
|
35
|
+
run: |
|
|
36
|
+
[[ "$RELEASE_TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]] || {
|
|
37
|
+
echo "Expected a release tag such as v0.20.0" >&2
|
|
38
|
+
exit 1
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
- name: Checkout release
|
|
42
|
+
uses: actions/checkout@v4
|
|
43
|
+
with:
|
|
44
|
+
ref: refs/tags/${{ inputs.tag }}
|
|
45
|
+
|
|
46
|
+
- name: Set image metadata
|
|
47
|
+
id: image
|
|
48
|
+
env:
|
|
49
|
+
RELEASE_TAG: ${{ inputs.tag }}
|
|
50
|
+
REPOSITORY: ${{ github.repository }}
|
|
51
|
+
TARGET: ${{ matrix.target }}
|
|
52
|
+
run: |
|
|
53
|
+
VERSION=${RELEASE_TAG#v}
|
|
54
|
+
IMAGE="ghcr.io/${REPOSITORY,,}"
|
|
55
|
+
SUFFIX=""
|
|
56
|
+
if [[ "$TARGET" == cli ]]; then SUFFIX="-cli"; fi
|
|
57
|
+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
|
58
|
+
echo "tag=$IMAGE:$VERSION$SUFFIX" >> "$GITHUB_OUTPUT"
|
|
59
|
+
|
|
60
|
+
- name: Set up QEMU
|
|
61
|
+
uses: docker/setup-qemu-action@v4
|
|
62
|
+
|
|
63
|
+
- name: Set up Docker Buildx
|
|
64
|
+
uses: docker/setup-buildx-action@v4
|
|
65
|
+
|
|
66
|
+
- name: Build smoke-test image
|
|
67
|
+
uses: docker/build-push-action@v7
|
|
68
|
+
with:
|
|
69
|
+
context: .
|
|
70
|
+
target: ${{ matrix.target }}
|
|
71
|
+
platforms: linux/amd64
|
|
72
|
+
load: true
|
|
73
|
+
tags: openhound-github:smoke
|
|
74
|
+
build-args: |
|
|
75
|
+
COLLECTOR_VERSION=${{ steps.image.outputs.version }}
|
|
76
|
+
cache-from: type=gha,scope=${{ matrix.target }}
|
|
77
|
+
|
|
78
|
+
- name: Verify runtime and installed collector
|
|
79
|
+
env:
|
|
80
|
+
EXPECTED_VERSION: ${{ steps.image.outputs.version }}
|
|
81
|
+
run: |
|
|
82
|
+
docker run --rm --entrypoint python -e EXPECTED_VERSION openhound-github:smoke -c '
|
|
83
|
+
import importlib.metadata as metadata
|
|
84
|
+
import os
|
|
85
|
+
import runpy
|
|
86
|
+
from unittest.mock import patch
|
|
87
|
+
import openhound_github.main
|
|
88
|
+
assert os.getuid() != 0
|
|
89
|
+
assert metadata.version("openhound-github") == os.environ["EXPECTED_VERSION"]
|
|
90
|
+
entries = metadata.entry_points(group="openhound.sources")
|
|
91
|
+
assert any(entry.name == "github" and entry.load() for entry in entries)
|
|
92
|
+
with patch.dict(os.environ, {
|
|
93
|
+
"DESTINATION__BLOODHOUNDENTERPRISE__URL": "https://example.invalid",
|
|
94
|
+
"DESTINATION__BLOODHOUNDENTERPRISE__TOKEN_ID": "smoke-test-id",
|
|
95
|
+
"DESTINATION__BLOODHOUNDENTERPRISE__TOKEN_KEY": "smoke-test-key",
|
|
96
|
+
}), patch("openhound.scheduler.service.Service", autospec=True) as service:
|
|
97
|
+
runpy.run_path("/app/src/scheduler.py", run_name="__main__")
|
|
98
|
+
assert service.call_args.kwargs["collector_name"] == "github"
|
|
99
|
+
service.return_value.start.assert_called_once_with()
|
|
100
|
+
'
|
|
101
|
+
|
|
102
|
+
- name: Verify CLI
|
|
103
|
+
if: matrix.target == 'cli'
|
|
104
|
+
run: docker run --rm openhound-github:smoke --help
|
|
105
|
+
|
|
106
|
+
- name: Log in to GHCR
|
|
107
|
+
uses: docker/login-action@v3
|
|
108
|
+
with:
|
|
109
|
+
registry: ghcr.io
|
|
110
|
+
username: ${{ github.actor }}
|
|
111
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
112
|
+
|
|
113
|
+
- name: Build and push multi-architecture image
|
|
114
|
+
uses: docker/build-push-action@v7
|
|
115
|
+
with:
|
|
116
|
+
context: .
|
|
117
|
+
target: ${{ matrix.target }}
|
|
118
|
+
platforms: linux/amd64,linux/arm64
|
|
119
|
+
push: true
|
|
120
|
+
sbom: true
|
|
121
|
+
tags: ${{ steps.image.outputs.tag }}
|
|
122
|
+
labels: |
|
|
123
|
+
org.opencontainers.image.source=https://github.com/${{ github.repository }}
|
|
124
|
+
org.opencontainers.image.version=${{ steps.image.outputs.version }}
|
|
125
|
+
build-args: |
|
|
126
|
+
COLLECTOR_VERSION=${{ steps.image.outputs.version }}
|
|
127
|
+
cache-from: type=gha,scope=${{ matrix.target }}
|
|
128
|
+
cache-to: type=gha,mode=max,scope=${{ matrix.target }}
|
|
@@ -14,10 +14,12 @@ on:
|
|
|
14
14
|
|
|
15
15
|
permissions:
|
|
16
16
|
contents: read
|
|
17
|
-
id-token: write
|
|
18
17
|
|
|
19
18
|
jobs:
|
|
20
19
|
build:
|
|
20
|
+
permissions:
|
|
21
|
+
contents: read
|
|
22
|
+
id-token: write
|
|
21
23
|
environment: pypi
|
|
22
24
|
runs-on: ubuntu-latest
|
|
23
25
|
|
|
@@ -44,3 +46,18 @@ jobs:
|
|
|
44
46
|
|
|
45
47
|
- name: Publish package
|
|
46
48
|
run: uv publish
|
|
49
|
+
|
|
50
|
+
container:
|
|
51
|
+
needs: build
|
|
52
|
+
permissions:
|
|
53
|
+
contents: read
|
|
54
|
+
packages: write
|
|
55
|
+
if: >-
|
|
56
|
+
github.repository == 'SpecterOps/openhound-github' &&
|
|
57
|
+
github.event_name == 'pull_request' &&
|
|
58
|
+
github.event.action == 'closed' &&
|
|
59
|
+
github.event.pull_request.merged == true &&
|
|
60
|
+
github.event.pull_request.base.ref == 'main'
|
|
61
|
+
uses: ./.github/workflows/publish-container.yml
|
|
62
|
+
with:
|
|
63
|
+
tag: ${{ inputs.tag || github.ref_name }}
|
|
@@ -11,10 +11,20 @@ on:
|
|
|
11
11
|
- "pyproject.toml"
|
|
12
12
|
- "uv.lock"
|
|
13
13
|
- "README.md"
|
|
14
|
+
- "Dockerfile"
|
|
15
|
+
- ".dockerignore"
|
|
16
|
+
- ".github/workflows/publish.yml"
|
|
17
|
+
- ".github/workflows/publish-container.yml"
|
|
14
18
|
|
|
15
19
|
permissions:
|
|
16
20
|
contents: write
|
|
17
21
|
id-token: write # This is required for requesting the JWT for the OIDC provider
|
|
22
|
+
packages: write
|
|
23
|
+
|
|
24
|
+
concurrency:
|
|
25
|
+
group: release-main
|
|
26
|
+
queue: max
|
|
27
|
+
cancel-in-progress: false
|
|
18
28
|
|
|
19
29
|
jobs:
|
|
20
30
|
|
|
@@ -28,18 +38,23 @@ jobs:
|
|
|
28
38
|
# needs: test-core
|
|
29
39
|
if: github.event.pull_request.merged == true
|
|
30
40
|
runs-on: ubuntu-latest
|
|
41
|
+
outputs:
|
|
42
|
+
new_version: ${{ steps.versioning.outputs.new_version }}
|
|
31
43
|
|
|
32
44
|
steps:
|
|
33
45
|
- name: Checkout
|
|
34
46
|
uses: actions/checkout@v4
|
|
35
47
|
with:
|
|
36
48
|
fetch-depth: 0
|
|
49
|
+
ref: ${{ github.event.pull_request.merge_commit_sha }}
|
|
37
50
|
|
|
38
51
|
- name: Fetch tags
|
|
39
52
|
run: git fetch --tags
|
|
40
53
|
|
|
41
54
|
- name: Determine next version
|
|
42
55
|
id: versioning
|
|
56
|
+
env:
|
|
57
|
+
BRANCH_NAME: ${{ github.event.pull_request.head.ref }}
|
|
43
58
|
run: |
|
|
44
59
|
# Get latest tag or fallback
|
|
45
60
|
LATEST_TAG=$(git tag --sort=-v:refname | head -n 1)
|
|
@@ -52,7 +67,6 @@ jobs:
|
|
|
52
67
|
VERSION=${LATEST_TAG#v}
|
|
53
68
|
IFS='.' read -r MAJOR MINOR PATCH <<< "$VERSION"
|
|
54
69
|
|
|
55
|
-
BRANCH_NAME="${{ github.event.pull_request.head.ref }}"
|
|
56
70
|
echo "Merged branch: $BRANCH_NAME"
|
|
57
71
|
|
|
58
72
|
if [[ "$BRANCH_NAME" == fix/* || "$BRANCH_NAME" == patch/* || "$BRANCH_NAME" == chore/* ]]; then
|
|
@@ -86,7 +100,7 @@ jobs:
|
|
|
86
100
|
|
|
87
101
|
publish:
|
|
88
102
|
needs: tag-release
|
|
89
|
-
if:
|
|
103
|
+
if: needs.tag-release.outputs.new_version != ''
|
|
90
104
|
uses: ./.github/workflows/publish.yml
|
|
91
105
|
with:
|
|
92
106
|
tag: ${{ needs.tag-release.outputs.new_version }}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# syntax=docker/dockerfile:1
|
|
2
|
+
FROM ghcr.io/astral-sh/uv:python3.13-trixie-slim AS builder
|
|
3
|
+
|
|
4
|
+
ENV UV_COMPILE_BYTECODE=1 \
|
|
5
|
+
UV_LINK_MODE=copy \
|
|
6
|
+
UV_PYTHON_DOWNLOADS=0
|
|
7
|
+
|
|
8
|
+
ARG COLLECTOR_VERSION
|
|
9
|
+
ENV SETUPTOOLS_SCM_PRETEND_VERSION=${COLLECTOR_VERSION}
|
|
10
|
+
|
|
11
|
+
WORKDIR /app
|
|
12
|
+
COPY pyproject.toml uv.lock README.md LICENSE.md ./
|
|
13
|
+
COPY src ./src
|
|
14
|
+
RUN test -n "$COLLECTOR_VERSION"
|
|
15
|
+
RUN --mount=type=cache,target=/root/.cache/uv \
|
|
16
|
+
uv sync --no-dev --group container --frozen --no-editable
|
|
17
|
+
|
|
18
|
+
FROM gcr.io/distroless/python3-debian13:nonroot AS base
|
|
19
|
+
|
|
20
|
+
ENV PYTHONDONTWRITEBYTECODE=1 \
|
|
21
|
+
PYTHONUNBUFFERED=1 \
|
|
22
|
+
PYTHONPATH=/app/.venv/lib/python3.13/site-packages \
|
|
23
|
+
LOG_CONTAINER=true \
|
|
24
|
+
RUNTIME__LOG_PATH=/app/logs \
|
|
25
|
+
DESTINATION__BLOODHOUNDENTERPRISE__COLLECTOR_NAME=github
|
|
26
|
+
|
|
27
|
+
COPY --from=builder --chown=nonroot:nonroot /app /app
|
|
28
|
+
WORKDIR /app
|
|
29
|
+
|
|
30
|
+
FROM base AS cli
|
|
31
|
+
ENTRYPOINT ["python", "-m", "openhound"]
|
|
32
|
+
CMD ["--help"]
|
|
33
|
+
|
|
34
|
+
FROM base AS enterprise
|
|
35
|
+
ENTRYPOINT ["python", "src/scheduler.py"]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: openhound-github
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.21.0
|
|
4
4
|
Summary: Github collector for OpenHound
|
|
5
5
|
Author-email: "jdreijer@specterops.io" <jdreijer@specterops.io>, Jared Atkinson <jatkinson@specterops.io>
|
|
6
6
|
License-File: LICENSE.md
|
|
@@ -154,3 +154,78 @@ Follow the OpenHound GitHub collector docs to get started:
|
|
|
154
154
|
- [Configure an organization GitHub App](https://bloodhound.specterops.io/openhound/collectors/github/configure-app)
|
|
155
155
|
- [Configure an enterprise GitHub App](https://bloodhound.specterops.io/openhound/collectors/github/configure-enterprise-app)
|
|
156
156
|
- [Configure a personal access token](https://bloodhound.specterops.io/openhound/collectors/github/configure-pat)
|
|
157
|
+
|
|
158
|
+
## Container images
|
|
159
|
+
|
|
160
|
+
After a release-triggering pull request merges into `main` in
|
|
161
|
+
`SpecterOps/openhound-github`, the release workflow publishes the PyPI package
|
|
162
|
+
first, then builds images for `linux/amd64` and `linux/arm64` in GitHub Container
|
|
163
|
+
Registry. Container builds are skipped for forks, other branches, and standalone
|
|
164
|
+
tag pushes. Both images use the same release version:
|
|
165
|
+
|
|
166
|
+
- `ghcr.io/specterops/openhound-github:<version>` starts the BloodHound Enterprise scheduler.
|
|
167
|
+
- `ghcr.io/specterops/openhound-github:<version>-cli` runs the OpenHound CLI.
|
|
168
|
+
|
|
169
|
+
For example, release tag `v0.20.0` produces image tags `0.20.0` and `0.20.0-cli`.
|
|
170
|
+
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.
|
|
172
|
+
|
|
173
|
+
### Run the scheduler
|
|
174
|
+
|
|
175
|
+
Prepare your `.dlt/config.toml`, `.dlt/secrets.toml`, and GitHub App private key
|
|
176
|
+
following the collector configuration documentation above. Mount the directory
|
|
177
|
+
read-only and use the container path for the key (for example,
|
|
178
|
+
`/app/.dlt/github-app.pem`). The container runs as UID/GID `65532`; mounted
|
|
179
|
+
files must be readable by that user.
|
|
180
|
+
|
|
181
|
+
```sh
|
|
182
|
+
docker run --rm --init \
|
|
183
|
+
--mount type=bind,src="$(pwd)/.dlt",dst=/app/.dlt,readonly \
|
|
184
|
+
ghcr.io/specterops/openhound-github:<version>
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Set the BloodHound Enterprise destination URL, token ID, and token key in
|
|
188
|
+
`.dlt/secrets.toml`:
|
|
189
|
+
|
|
190
|
+
```toml
|
|
191
|
+
[destination.bloodhoundenterprise]
|
|
192
|
+
url = "https://<tenant>.bloodhoundenterprise.io"
|
|
193
|
+
token_id = "<token-id>"
|
|
194
|
+
token_key = "<token-key>"
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
The image defaults the collector name to `github`. OpenHound manages the
|
|
198
|
+
scheduler polling interval internally. Collection state and output are stored
|
|
199
|
+
inside the container unless you mount persistent storage for them.
|
|
200
|
+
|
|
201
|
+
To inspect the CLI:
|
|
202
|
+
|
|
203
|
+
```sh
|
|
204
|
+
docker run --rm ghcr.io/specterops/openhound-github:<version>-cli --help
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Build and publish
|
|
208
|
+
|
|
209
|
+
To build locally without publishing:
|
|
210
|
+
|
|
211
|
+
```sh
|
|
212
|
+
docker build --target cli --build-arg COLLECTOR_VERSION=0.20.0 \
|
|
213
|
+
-t openhound-github:0.20.0-cli .
|
|
214
|
+
docker build --target enterprise --build-arg COLLECTOR_VERSION=0.20.0 \
|
|
215
|
+
-t openhound-github:0.20.0 .
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
`COLLECTOR_VERSION` sets the GitHub collector package version; the OpenHound
|
|
219
|
+
framework version is resolved separately from `uv.lock`. The container-only
|
|
220
|
+
dependency group installs the framework without development tools.
|
|
221
|
+
|
|
222
|
+
To retry a failed container publication, re-run the failed jobs in the original
|
|
223
|
+
release workflow run. The container workflow authenticates using `GITHUB_TOKEN`
|
|
224
|
+
with `packages: write`; AWS credentials and personal access tokens are not
|
|
225
|
+
needed. Runtime checks run before each image is pushed, and both architectures
|
|
226
|
+
include an SBOM.
|
|
227
|
+
|
|
228
|
+
After the first publication, a package administrator should verify the GHCR
|
|
229
|
+
package's visibility and repository access. New packages default to private;
|
|
230
|
+
make the package public if anonymous pulls are intended. If the package
|
|
231
|
+
already exists, grant this repository's Actions workflows write access to it.
|
|
@@ -143,3 +143,78 @@ Follow the OpenHound GitHub collector docs to get started:
|
|
|
143
143
|
- [Configure an organization GitHub App](https://bloodhound.specterops.io/openhound/collectors/github/configure-app)
|
|
144
144
|
- [Configure an enterprise GitHub App](https://bloodhound.specterops.io/openhound/collectors/github/configure-enterprise-app)
|
|
145
145
|
- [Configure a personal access token](https://bloodhound.specterops.io/openhound/collectors/github/configure-pat)
|
|
146
|
+
|
|
147
|
+
## Container images
|
|
148
|
+
|
|
149
|
+
After a release-triggering pull request merges into `main` in
|
|
150
|
+
`SpecterOps/openhound-github`, the release workflow publishes the PyPI package
|
|
151
|
+
first, then builds images for `linux/amd64` and `linux/arm64` in GitHub Container
|
|
152
|
+
Registry. Container builds are skipped for forks, other branches, and standalone
|
|
153
|
+
tag pushes. Both images use the same release version:
|
|
154
|
+
|
|
155
|
+
- `ghcr.io/specterops/openhound-github:<version>` starts the BloodHound Enterprise scheduler.
|
|
156
|
+
- `ghcr.io/specterops/openhound-github:<version>-cli` runs the OpenHound CLI.
|
|
157
|
+
|
|
158
|
+
For example, release tag `v0.20.0` produces image tags `0.20.0` and `0.20.0-cli`.
|
|
159
|
+
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.
|
|
161
|
+
|
|
162
|
+
### Run the scheduler
|
|
163
|
+
|
|
164
|
+
Prepare your `.dlt/config.toml`, `.dlt/secrets.toml`, and GitHub App private key
|
|
165
|
+
following the collector configuration documentation above. Mount the directory
|
|
166
|
+
read-only and use the container path for the key (for example,
|
|
167
|
+
`/app/.dlt/github-app.pem`). The container runs as UID/GID `65532`; mounted
|
|
168
|
+
files must be readable by that user.
|
|
169
|
+
|
|
170
|
+
```sh
|
|
171
|
+
docker run --rm --init \
|
|
172
|
+
--mount type=bind,src="$(pwd)/.dlt",dst=/app/.dlt,readonly \
|
|
173
|
+
ghcr.io/specterops/openhound-github:<version>
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Set the BloodHound Enterprise destination URL, token ID, and token key in
|
|
177
|
+
`.dlt/secrets.toml`:
|
|
178
|
+
|
|
179
|
+
```toml
|
|
180
|
+
[destination.bloodhoundenterprise]
|
|
181
|
+
url = "https://<tenant>.bloodhoundenterprise.io"
|
|
182
|
+
token_id = "<token-id>"
|
|
183
|
+
token_key = "<token-key>"
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
The image defaults the collector name to `github`. OpenHound manages the
|
|
187
|
+
scheduler polling interval internally. Collection state and output are stored
|
|
188
|
+
inside the container unless you mount persistent storage for them.
|
|
189
|
+
|
|
190
|
+
To inspect the CLI:
|
|
191
|
+
|
|
192
|
+
```sh
|
|
193
|
+
docker run --rm ghcr.io/specterops/openhound-github:<version>-cli --help
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Build and publish
|
|
197
|
+
|
|
198
|
+
To build locally without publishing:
|
|
199
|
+
|
|
200
|
+
```sh
|
|
201
|
+
docker build --target cli --build-arg COLLECTOR_VERSION=0.20.0 \
|
|
202
|
+
-t openhound-github:0.20.0-cli .
|
|
203
|
+
docker build --target enterprise --build-arg COLLECTOR_VERSION=0.20.0 \
|
|
204
|
+
-t openhound-github:0.20.0 .
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
`COLLECTOR_VERSION` sets the GitHub collector package version; the OpenHound
|
|
208
|
+
framework version is resolved separately from `uv.lock`. The container-only
|
|
209
|
+
dependency group installs the framework without development tools.
|
|
210
|
+
|
|
211
|
+
To retry a failed container publication, re-run the failed jobs in the original
|
|
212
|
+
release workflow run. The container workflow authenticates using `GITHUB_TOKEN`
|
|
213
|
+
with `packages: write`; AWS credentials and personal access tokens are not
|
|
214
|
+
needed. Runtime checks run before each image is pushed, and both architectures
|
|
215
|
+
include an SBOM.
|
|
216
|
+
|
|
217
|
+
After the first publication, a package administrator should verify the GHCR
|
|
218
|
+
package's visibility and repository access. New packages default to private;
|
|
219
|
+
make the package public if anonymous pulls are intended. If the package
|
|
220
|
+
already exists, grant this repository's Actions workflows write access to it.
|
|
@@ -7,6 +7,7 @@ from .branch_push_allowance import BranchPushAllowance
|
|
|
7
7
|
from .classic_personal_access_token import ClassicPersonalAccessToken
|
|
8
8
|
from .enterprise import Enterprise
|
|
9
9
|
from .enterprise_admin import EnterpriseAdmin
|
|
10
|
+
from .enterprise_credential_inventory import EnterpriseCredentialInventory
|
|
10
11
|
from .enterprise_helpers import enterprise_role_node_id, enterprise_team_node_id
|
|
11
12
|
from .enterprise_managed_user import EnterpriseManagedUser
|
|
12
13
|
from .enterprise_member import BaseUser, flatten_enterprise_member
|
|
@@ -140,6 +141,7 @@ __all__ = [
|
|
|
140
141
|
"DeployKey",
|
|
141
142
|
"Enterprise",
|
|
142
143
|
"EnterpriseAdmin",
|
|
144
|
+
"EnterpriseCredentialInventory",
|
|
143
145
|
"EnterpriseManagedUser",
|
|
144
146
|
"EnterpriseOrganization",
|
|
145
147
|
"EnterpriseRole",
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class EnterpriseCredentialInventory(BaseModel):
|
|
7
|
+
"""A downloaded credential export, before credential-specific parsing.
|
|
8
|
+
|
|
9
|
+
Keep CSV fields as raw values so unknown credential types and new columns
|
|
10
|
+
survive collection. DLT returns dictionaries for the downstream parser.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
export_id: str
|
|
14
|
+
as_of: str | None = None
|
|
15
|
+
created_with_fallback: bool
|
|
16
|
+
columns: list[str]
|
|
17
|
+
rows: list[dict[str, Any]]
|
|
18
|
+
enterprise_node_id: str
|
|
19
|
+
enterprise_name: str
|
{openhound_github-0.20.1 → openhound_github-0.21.0}/src/openhound_github/resources/enterprise.py
RENAMED
|
@@ -37,6 +37,7 @@ from openhound_github.models import (
|
|
|
37
37
|
ClassicPersonalAccessToken,
|
|
38
38
|
Enterprise,
|
|
39
39
|
EnterpriseAdmin,
|
|
40
|
+
EnterpriseCredentialInventory,
|
|
40
41
|
EnterpriseManagedUser,
|
|
41
42
|
EnterpriseOrganization,
|
|
42
43
|
EnterpriseRunner,
|
|
@@ -285,7 +286,7 @@ def _download_enterprise_credential_inventory(
|
|
|
285
286
|
|
|
286
287
|
@app.transformer(
|
|
287
288
|
name="enterprise_credential_inventory",
|
|
288
|
-
columns=
|
|
289
|
+
columns=EnterpriseCredentialInventory,
|
|
289
290
|
parallelized=True,
|
|
290
291
|
)
|
|
291
292
|
def enterprise_credential_inventory(enterprise_data: Enterprise, ctx: SourceContext):
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""Start the BloodHound Enterprise scheduler for the configured collector."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
|
|
5
|
+
import dlt
|
|
6
|
+
|
|
7
|
+
from openhound.scheduler.service import Service
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def start() -> None:
|
|
13
|
+
collector_name = dlt.config["destination.bloodhoundenterprise.collector_name"]
|
|
14
|
+
logger.info("Initializing service for collector '%s'.", collector_name)
|
|
15
|
+
service = Service(
|
|
16
|
+
bhe_uri=dlt.secrets["destination.bloodhoundenterprise.url"],
|
|
17
|
+
token_key=dlt.secrets["destination.bloodhoundenterprise.token_key"],
|
|
18
|
+
token_id=dlt.secrets["destination.bloodhoundenterprise.token_id"],
|
|
19
|
+
collector_name=collector_name,
|
|
20
|
+
)
|
|
21
|
+
service.start()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
if __name__ == "__main__":
|
|
25
|
+
start()
|
{openhound_github-0.20.1 → openhound_github-0.21.0}/tests/test_classic_personal_access_tokens.py
RENAMED
|
@@ -6,18 +6,20 @@ from types import SimpleNamespace
|
|
|
6
6
|
from unittest.mock import MagicMock
|
|
7
7
|
|
|
8
8
|
import dlt
|
|
9
|
+
import duckdb
|
|
9
10
|
import pytest
|
|
10
11
|
import requests
|
|
11
|
-
import
|
|
12
|
+
from dlt.common.schema.exceptions import DataValidationError
|
|
12
13
|
from dlt.destinations import filesystem
|
|
14
|
+
from dlt.extract.validation import PydanticValidator
|
|
13
15
|
|
|
14
16
|
from openhound_github.kinds import edges as ek
|
|
15
17
|
from openhound_github.lookup import GithubLookup
|
|
16
18
|
from openhound_github.models.classic_personal_access_token import (
|
|
17
19
|
ClassicPersonalAccessToken,
|
|
18
20
|
)
|
|
19
|
-
from openhound_github.models.enterprise_member import BaseUser
|
|
20
21
|
from openhound_github.models.enterprise import Enterprise
|
|
22
|
+
from openhound_github.models.enterprise_member import BaseUser
|
|
21
23
|
from openhound_github.resources.enterprise import (
|
|
22
24
|
SourceContext,
|
|
23
25
|
_download_enterprise_credential_inventory,
|
|
@@ -53,6 +55,43 @@ class Response:
|
|
|
53
55
|
yield self.content[offset : offset + chunk_size]
|
|
54
56
|
|
|
55
57
|
|
|
58
|
+
def test_inventory_validator_preserves_raw_csv_for_token_parser(monkeypatch):
|
|
59
|
+
validator = enterprise_credential_inventory.validator
|
|
60
|
+
assert isinstance(validator, PydanticValidator)
|
|
61
|
+
monkeypatch.setattr(
|
|
62
|
+
validator, "table_name", enterprise_credential_inventory.name, raising=False
|
|
63
|
+
)
|
|
64
|
+
assert enterprise_credential_inventory.columns["columns"]["data_type"] == "json"
|
|
65
|
+
assert enterprise_credential_inventory.columns["rows"]["data_type"] == "json"
|
|
66
|
+
|
|
67
|
+
inventory = {
|
|
68
|
+
"export_id": "export-1",
|
|
69
|
+
"as_of": None,
|
|
70
|
+
"created_with_fallback": False,
|
|
71
|
+
"enterprise_node_id": "E_1",
|
|
72
|
+
"enterprise_name": "enterprise",
|
|
73
|
+
"columns": ["credential_type", "credential_id", "new_csv_column"],
|
|
74
|
+
"rows": [
|
|
75
|
+
{"credential_type": "classic_pat", "credential_id": "invalid"},
|
|
76
|
+
{"credential_type": "classic_pat", "credential_id": "42"},
|
|
77
|
+
{
|
|
78
|
+
"credential_type": "future_credential_type",
|
|
79
|
+
"credential_id": "007",
|
|
80
|
+
"new_csv_column": None,
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
}
|
|
84
|
+
validated = validator(inventory)
|
|
85
|
+
assert isinstance(validated, dict)
|
|
86
|
+
assert validated == inventory
|
|
87
|
+
tokens = list(classic_personal_access_tokens.__wrapped__(validated))
|
|
88
|
+
assert [token["credential_id"] for token in tokens] == [42]
|
|
89
|
+
|
|
90
|
+
# Validate the envelope without applying credential-specific rules to CSV rows.
|
|
91
|
+
with pytest.raises(DataValidationError):
|
|
92
|
+
validator({**inventory, "rows": "not a list of rows"})
|
|
93
|
+
|
|
94
|
+
|
|
56
95
|
def test_classic_pat_export_polls_one_job_and_deduplicates_org_rows(monkeypatch):
|
|
57
96
|
client = MagicMock()
|
|
58
97
|
client.post.return_value = Response(
|
|
@@ -180,6 +219,7 @@ def test_one_export_persists_raw_rows_and_models_only_classic_pats(
|
|
|
180
219
|
return {
|
|
181
220
|
"export_id": "export-1",
|
|
182
221
|
"as_of": "2026-10-05T20:00:00Z",
|
|
222
|
+
"created_with_fallback": False,
|
|
183
223
|
"columns": ["credential_type", "credential_id", "hashed_token"],
|
|
184
224
|
"rows": [
|
|
185
225
|
{
|
|
@@ -879,6 +879,9 @@ dependencies = [
|
|
|
879
879
|
]
|
|
880
880
|
|
|
881
881
|
[package.dev-dependencies]
|
|
882
|
+
container = [
|
|
883
|
+
{ name = "openhound" },
|
|
884
|
+
]
|
|
882
885
|
dev = [
|
|
883
886
|
{ name = "mypy" },
|
|
884
887
|
{ name = "openhound" },
|
|
@@ -895,6 +898,9 @@ requires-dist = [
|
|
|
895
898
|
]
|
|
896
899
|
|
|
897
900
|
[package.metadata.requires-dev]
|
|
901
|
+
container = [
|
|
902
|
+
{ name = "openhound", specifier = ">=0.4.0" },
|
|
903
|
+
]
|
|
898
904
|
dev = [
|
|
899
905
|
{ name = "mypy", specifier = ">=1.19.1" },
|
|
900
906
|
{ name = "openhound", specifier = ">=0.4.0" },
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openhound_github-0.20.1 → openhound_github-0.21.0}/descriptions/edges/GH_AddCollaborator.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|