github

package
v0.88.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 21, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package github implements the github source plugin: it reads a single GitHub organization and emits six cloud-neutral evidence types — git_repository, directory_user, source_control_org_policy, vulnerability_finding, pull_request and deployment — suitable for SOC 2 branch-protection, 2FA-coverage and change-management policies.

The first four are point-in-time configuration snapshots. The last two are PERIOD-SCOPED: they report what happened between the audit window's period_start and period_end (injected as native time.Time slot params by the orchestrator), not what is configured now.

Per the KISS-no-DRY axiom (docs/architecture/04-source-plugins.md §The plugin contract), the plugin caches nothing across Collect calls. N policies bound to this plugin → N invocations of Collect.

Test injection: the API interface mirrors the pattern used by internal/sources/aws/iam — the concrete *httpAPI satisfies it, and unit tests inject an in-memory fake. The real HTTP adapter has no integration tests today (deferred — live API integration tests are out of scope for this batch).

Index

Constants

View Source
const (
	EvidenceTypeRepository    = "git_repository"
	EvidenceTypeDirectoryUser = "directory_user"
	EvidenceTypeOrgPolicy     = "source_control_org_policy"
	EvidenceTypeVulnerability = "vulnerability_finding"
	EvidenceTypePullRequest   = "pull_request"
	EvidenceTypeDeployment    = "deployment"
)

Evidence type IDs this plugin emits.

EvidenceTypeRepository is the cross-vendor git_repository shape; GitHub is one of several substitutable source-code platforms (GitLab, Bitbucket, future Gitea/Azure DevOps). EvidenceTypeDirectoryUser is the cross-vendor directory_user shape — GitHub org members are one of several substitutable directory sources (AWS IAM, Okta, future Azure AD/LDAP). EvidenceTypeOrgPolicy is the cross-vendor source_control_org_policy shape — a single org/group-level governance record (GitHub org, GitLab group, Bitbucket workspace). EvidenceTypeVulnerability is the cross-vendor vulnerability_finding shape — one record per open Dependabot alert; GitHub is one of several substitutable finding sources (AWS Inspector, GCP SCC). EvidenceTypePullRequest is the cross-vendor pull_request shape — one record per change MERGED during the audit period (GitHub PR, GitLab MR, Bitbucket PR). It answers "did this change actually get reviewed?", which the git_repository configuration snapshot cannot. EvidenceTypeDeployment is the cross-vendor deployment shape — one record per release to a running environment during the period.

View Source
const SourceID = "github"

SourceID is the registered ID for the github plugin instance.

Variables

This section is empty.

Functions

This section is empty.

Types

type API

type API interface {
	// ListRepos returns all repos in the configured organization.
	// Implementations must page transparently — callers receive the
	// full list in one slice.
	ListRepos(ctx context.Context) ([]Repo, error)
	// ListOrgMembers returns all members of the configured org along
	// with their 2FA state and role. 2FA state requires admin scope.
	ListOrgMembers(ctx context.Context) ([]Member, error)
	// ListOutsideCollaborators returns users with access to org repos
	// who are not org members (external identities). 2FA state requires
	// admin scope; these users carry no org role.
	ListOutsideCollaborators(ctx context.Context) ([]Member, error)
	// GetOrgPolicy returns the configured org's governance settings.
	// The org-settings fields (2FA requirement, default permission)
	// require an org-admin-scoped token.
	GetOrgPolicy(ctx context.Context) (OrgPolicy, error)
	// ListDependabotAlerts returns the org's open Dependabot alerts.
	// Requires a token with security-events read access; when Dependabot
	// alerts are disabled for the org (403) the implementation returns an
	// empty slice rather than an error, so the per-repo enablement gap is
	// reported by the dependabot_alerts_enabled policy instead of failing
	// the run.
	ListDependabotAlerts(ctx context.Context) ([]DependabotAlert, error)
	// ListMergedPullRequests returns the org's pull requests merged into
	// each repository's default branch with a merge timestamp inside
	// [start, end]. GitHub's pulls listing has no date filter, so
	// implementations paginate newest-updated-first and stop once a page
	// predates start. A repository the token cannot read is skipped, not
	// an error — one inaccessible repo must not fail the whole run.
	ListMergedPullRequests(ctx context.Context, start, end time.Time) ([]PullRequest, error)
	// ListDeployments returns the org's deployments created inside
	// [start, end], including failed ones. Same pagination and
	// per-repository error tolerance as ListMergedPullRequests.
	ListDeployments(ctx context.Context, start, end time.Time) ([]Deployment, error)
}

API is the subset of the GitHub REST API the plugin uses. Defining it as an interface lets tests inject a fake without making real network calls; the concrete *httpAPI satisfies it.

type CheckRun added in v0.71.0

type CheckRun struct {
	Status     string
	Conclusion string
}

CheckRun is one automated check associated with a pull request's head commit. Status is GitHub's lifecycle state (queued / in_progress / completed) and Conclusion its outcome (success / failure / neutral / canceled / skipped / timed_out / action_required).

type DependabotAlert added in v0.36.0

type DependabotAlert struct {
	Number       int
	RepoFullName string
	PackageName  string
	Summary      string
	Severity     string
	State        string
	CVEID        string
	CVSSScore    float64
	// PatchAvailable is true when GitHub reports a first patched version.
	PatchAvailable bool
}

DependabotAlert is the subset of an org Dependabot alert the plugin maps to one vulnerability_finding record. Severity and State carry GitHub's raw vocabulary (low/medium/high/critical, open/dismissed/ fixed); the plugin normalizes them to the evidence type's enums.

type Deployment added in v0.71.0

type Deployment struct {
	Repository string
	// ID is the vendor-native deployment identifier as a string.
	ID          string
	SHA         string
	Environment string
	// ProductionEnvironment is GitHub's production_environment flag. The
	// field is frequently absent from the API response; the adapter
	// treats absent as false and the plugin falls back to the
	// environment name when deriving is_production.
	ProductionEnvironment bool
	Creator               string
	CreatedAt             time.Time
	State                 string
}

Deployment is one release of code to a running environment during the audit period, including failed ones. State carries the raw latest GitHub deployment-status state (success / error / failure / pending / queued / in_progress / inactive) and is empty when the deployment has no status entries at all; the plugin normalizes it to the evidence type's closed vocabulary.

type Member

type Member struct {
	Login       string
	TwoFactorOn bool
	Role        string
}

Member is the subset of fields the plugin extracts from an org member listing.

type Options

type Options struct {
	API API
	Org string
	// Now is injected so tests can produce deterministic CollectedAt
	// values. Production callers leave it nil → time.Now().UTC().
	Now func() time.Time
}

Options is the constructor input.

type OrgPolicy added in v0.36.0

type OrgPolicy struct {
	// TwoFactorRequired is the org-wide MFA enforcement flag. GitHub
	// reports this as a tri-state (true/false/null when the caller lacks
	// admin scope); the adapter normalizes null to false.
	TwoFactorRequired bool
	// DefaultRepoPermission is the baseline member permission: one of
	// none/read/write/admin (GitHub's default_repository_permission).
	DefaultRepoPermission string

	MembersCanCreatePublicRepos bool
	WebCommitSignoffRequired    bool
	AdvancedSecurityNewRepos    bool
	SecretScanningNewRepos      bool
	DependabotAlertsNewRepos    bool
}

OrgPolicy is the org/group-level governance state the plugin extracts from a single organization. Exactly one OrgPolicy maps to one source_control_org_policy record. Every field maps to a property of that evidence type so policies never read an absent field.

type Plugin

type Plugin struct {
	// contains filtered or unexported fields
}

Plugin is the in-process github source.

func New

func New(opts Options) *Plugin

New constructs a Plugin around an explicit API implementation. Callers using the real GitHub REST API should use NewFromToken.

func NewFromToken

func NewFromToken(_ context.Context, org, token, baseURL string) (*Plugin, error)

NewFromToken constructs a Plugin backed by the real GitHub REST API using the supplied personal-access or app token. A blank baseURL defaults to github.com; GitHub Enterprise Server instances pass their own URL. Live integration tests are deferred.

func (*Plugin) Caveats added in v0.85.0

func (*Plugin) Caveats() []core.SourceCaveat

Caveats declares the one field this plugin can emit without observing it.

Conditional, not absolute: GitHub really does publish the org-wide 2FA requirement, but GET /orgs/{org} returns two_factor_requirement_enabled as a tri-state — true, false, or null when the caller lacks the admin:org scope. GetOrgPolicy flattens null to false (the field is a bool on the wire type and a policy reading an absent field is an error, so some value must be chosen), and it does so silently: no error is returned and nothing is logged, because the rest of the org record is still perfectly usable. What that leaves is a false that an org-wide-MFA policy grades as a real "2FA is not enforced", with nothing in the run to distinguish it from "we were not allowed to look". The caveat is what says it.

Declared unconditionally because token scope is not known at plan time: the org read happens during collection, long after the planner has to decide whether to warn. Over-warning a correctly-scoped token is the cheaper error.

Deliberately NOT declared for directory_user.mfa_enabled, which needs the same scope: there the 2fa_disabled listing's failure is RETURNED from ListOrgMembers, so an unscoped token errors the policy instead of quietly grading it on a fabricated value. A caveat warns about a silent gap; that one is not silent, and warning about it would dilute the ones that are.

func (*Plugin) Collect

func (p *Plugin) Collect(ctx context.Context, req core.SlotRequest) ([]core.EvidenceRecord, error)

Collect returns records for every evidence type in req.AcceptedTypes that this plugin emits. A slot whose Accepts list names several github types gets records for all of them in a single call. Records are sorted by ID within each type group; the collector splits them by Type for envelope writing.

func (*Plugin) Emits

func (*Plugin) Emits() []string

Emits returns the evidence types this plugin can produce.

func (*Plugin) ID

func (*Plugin) ID() string

ID returns the registered plugin ID.

func (*Plugin) Init

func (*Plugin) Init(context.Context, map[string]any) error

Init is a no-op; the constructor has already received configuration.

type PullRequest added in v0.71.0

type PullRequest struct {
	// Repository is the `org/repo` form, matching git_repository.name.
	Repository     string
	Number         int
	Author         string
	MergedBy       string
	TargetBranch   string
	MergeCommitSHA string
	MergedAt       time.Time
	Reviews        []Review
	CheckRuns      []CheckRun
}

PullRequest is one change MERGED into a repository during the audit period. The adapter supplies the raw vendor facts (including the full review history and the head commit's check runs); the plugin derives approval_count / independent_approval_count / approved_before_merge / checks_passed from them, so the normalization is unit-testable without a network.

type Repo

type Repo struct {
	Name            string
	DefaultBranch   string
	ProtectionOn    bool
	RequiredReviews int

	// Branch-protection rule details (default branch).
	RequiresSignedCommits   bool
	RequiresLinearHistory   bool
	AllowsForcePush         bool
	DismissStaleReviews     bool
	RequireCodeOwnerReviews bool

	// Repository attributes.
	IsPrivate bool
	Archived  bool

	// Code-security and analysis features.
	SecretScanningEnabled   bool
	PushProtectionEnabled   bool
	DependabotAlertsEnabled bool
	CodeScanningEnabled     bool
}

Repo is the subset of fields the plugin extracts from a repository listing. The plugin returns one record per Repo, augmented with branch-protection state and code-security settings queried via follow-up calls. Every field maps to a property of the git_repository evidence type so policies never read an absent field.

type Review added in v0.71.0

type Review struct {
	User        string
	State       string
	SubmittedAt time.Time
}

Review is one review a user submitted on a pull request. State carries GitHub's raw vocabulary (APPROVED / CHANGES_REQUESTED / COMMENTED / DISMISSED / PENDING); the plugin reduces the per-user review history to the approval counts the pull_request evidence type declares. SubmittedAt is the zero value when the vendor reports no timestamp.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL