Documentation
¶
Index ¶
- Constants
- func AvailableCategories() []string
- func AvailableSeverities() []string
- func DiscoverConfigPath(dir string) (string, error)
- func LoadRuleDocs(fsys fs.FS) error
- func ParseRepoURL(input string) (owner, repo string, err error)
- func SeverityOrder(severity string) int
- type ActionRef
- type ActionVersionPinningRuleOptions
- type ActionsSettingsFacts
- type Config
- type ConfigRuleOptions
- type ConfigRules
- type DebugLogger
- type DependabotConfig
- type DependabotCooldown
- type DependabotFacts
- type DependabotUpdate
- type FactWarning
- type Finding
- type RenovateConfig
- type RenovateFacts
- type RenovatePackageRule
- type RuleInfo
- type RuleOverride
- type RuleSuppression
- type ScanFacts
- type ScanOptions
- type ScanResult
- type Scanner
- type UpdateToolConfigurationRuleOptions
- type WorkflowFact
- type WorkflowFile
- type WorkflowJob
- type WorkflowStep
Constants ¶
const ( SeverityCritical = "critical" SeverityHigh = "high" SeverityMedium = "medium" SeverityLow = "low" SeverityInfo = "info" )
Severity levels for findings
Variables ¶
This section is empty.
Functions ¶
func AvailableCategories ¶
func AvailableCategories() []string
func AvailableSeverities ¶
func AvailableSeverities() []string
func DiscoverConfigPath ¶
func LoadRuleDocs ¶ added in v0.4.0
LoadRuleDocs parses every *.md file in fsys (a directory of rule pages) and populates the registry. Production passes the embedded docs/rules FS; tests pass os.DirFS pointed at the real files. It is safe to call more than once (the last call wins), which keeps test setup simple.
func ParseRepoURL ¶
ParseRepoURL extracts owner and repo from various GitHub URL formats
func SeverityOrder ¶
SeverityOrder returns a number for sorting (lower = more severe)
Types ¶
type ActionRef ¶
type ActionRef struct {
// contains filtered or unexported fields
}
ActionRef holds information about an action reference
type ActionVersionPinningRuleOptions ¶
type ActionVersionPinningRuleOptions struct {
IgnoreSameOwner bool `yaml:"ignore_same_owner"`
}
type ActionsSettingsFacts ¶
type ActionsSettingsFacts struct {
Permissions *github.ActionsPermissionsRepository
AccessFinding *Finding
DefaultWorkflowPermissions *github.DefaultWorkflowPermissionRepository
ForkPRContributorApproval *github.ContributorApprovalPermissions
}
type Config ¶
type Config struct {
Rules ConfigRules `yaml:"rules"`
RuleOptions ConfigRuleOptions `yaml:"rule_options"`
Overrides []RuleOverride `yaml:"overrides"`
Suppressions []RuleSuppression `yaml:"suppressions"`
}
func LoadConfig ¶
type ConfigRuleOptions ¶
type ConfigRuleOptions struct {
ActionVersionPinning ActionVersionPinningRuleOptions `yaml:"workflows/action-version-pinning"`
UpdateToolConfiguration UpdateToolConfigurationRuleOptions `yaml:"updates/update-tool-configuration"`
}
type ConfigRules ¶
type DebugLogger ¶
type DebugLogger func(repo, msg string)
DebugLogger is a function that receives a single-line debug message. The repo parameter is "owner/repo" and is included so interleaved batch output can be filtered or sorted by repository. When nil, debug output is suppressed entirely.
Fact collection runs concurrently, so a DebugLogger may be called from multiple goroutines at once and must be safe for concurrent use. Each call is expected to emit one whole line so interleaved output stays readable.
type DependabotConfig ¶
type DependabotConfig struct {
Version int `yaml:"version"`
Updates []DependabotUpdate `yaml:"updates"`
}
DependabotConfig represents a dependabot.yml configuration
type DependabotCooldown ¶
type DependabotCooldown struct {
DefaultDays int `yaml:"default-days"`
}
type DependabotFacts ¶
type DependabotFacts struct {
Path string
Content string
Config *DependabotConfig
Missing bool
Invalid error
HasWorkflows bool
// Unknown is set when presence could not be determined (an indeterminate
// fetch error, not a clean 404). It is mutually exclusive with Missing:
// when Unknown, rules must not treat the tool as absent.
Unknown bool
}
type DependabotUpdate ¶
type DependabotUpdate struct {
PackageEcosystem string `yaml:"package-ecosystem"`
Directory string `yaml:"directory"`
Schedule struct {
Interval string `yaml:"interval"`
} `yaml:"schedule"`
Cooldown *DependabotCooldown `yaml:"cooldown"`
OpenPullRequestsLimit int `yaml:"open-pull-requests-limit"`
}
DependabotUpdate represents a single update configuration
type FactWarning ¶ added in v0.4.0
FactWarning records a fact the scanner could not determine because a GitHub request failed for a reason other than a definitive "not found" — a timeout, cancellation, rate limit, 5xx, or network error. These are surfaced on ScanResult.Incomplete so a partial scan is never silently reported as clean.
The distinction matters because the collectors treat a 404 as a meaningful signal ("this config file does not exist"). An indeterminate failure is NOT that signal — we simply don't know — and conflating the two would either invent findings (e.g. "no update tool") or hide them.
func (FactWarning) String ¶ added in v0.4.0
func (w FactWarning) String() string
type Finding ¶
type Finding struct {
ID string `json:"id"`
Rule string `json:"rule,omitempty"`
Category string `json:"category,omitempty"`
Severity string `json:"severity"`
Success bool `json:"success"`
Title string `json:"title"`
Description string `json:"description"`
Location string `json:"location,omitempty"`
File string `json:"file,omitempty"`
Line int `json:"line,omitempty"`
Remediation string `json:"remediation"`
FixURL string `json:"fix_url,omitempty"`
DocURL string `json:"doc_url,omitempty"`
}
Finding represents a single security issue found during scanning
type RenovateConfig ¶
type RenovateConfig struct {
Extends []string `json:"extends"`
EnabledManagers []string `json:"enabledManagers"`
PinDigests bool `json:"pinDigests"`
MinReleaseAge string `json:"minimumReleaseAge"`
PackageRules []RenovatePackageRule `json:"packageRules"`
}
RenovateConfig represents a parsed Renovate configuration file. Only the fields relevant to our security checks are decoded.
type RenovateFacts ¶
type RenovateFacts struct {
Path string
Content string
Config *RenovateConfig
Missing bool
Invalid error
HasWorkflows bool
// Unknown is set when presence could not be determined (an indeterminate
// fetch error, not a clean 404). It is mutually exclusive with Missing:
// when Unknown, rules must not treat the tool as absent.
Unknown bool
}
type RenovatePackageRule ¶
type RenovatePackageRule struct {
MatchManagers []string `json:"matchManagers"`
MatchDepTypes []string `json:"matchDepTypes"`
PinDigests bool `json:"pinDigests"`
MinReleaseAge string `json:"minimumReleaseAge"`
}
RenovatePackageRule represents one entry in Renovate's packageRules array.
type RuleInfo ¶
type RuleInfo struct {
Name string `json:"name"`
Aliases []string `json:"aliases,omitempty"`
Title string `json:"title"`
Category string `json:"category"`
Severity string `json:"severity"`
Description string `json:"description"`
// DocFile is the slug of this rule's page under docs/rules/ (without the
// .md extension). It is the single source of truth that binds a rule to its
// in-repo documentation; DocURL() turns it into a link for reports.
DocFile string `json:"doc_file,omitempty"`
}
func AvailableRules ¶
func AvailableRules() []RuleInfo
func ResolveRuleNames ¶
type RuleOverride ¶
type RuleSuppression ¶
type ScanFacts ¶
type ScanFacts struct {
Repository *github.Repository
RepositoryOwner string
DefaultBranch string
Workflows []WorkflowFact
ActionsSettings ActionsSettingsFacts
Dependabot DependabotFacts
Renovate RenovateFacts
ActionVersionPinningIgnoreSameOwner bool
UpdateToolConfigurationRequireWorkflows bool
// Incomplete lists facts that could not be determined because a GitHub
// request failed for a reason other than a clean 404 (timeout, rate limit,
// 5xx, …). A non-empty slice means the scan is partial.
Incomplete []FactWarning
}
type ScanOptions ¶
type ScanResult ¶
type ScanResult struct {
RepoFullName string `json:"repo_full_name"`
RepoURL string `json:"repo_url"`
Findings []Finding `json:"findings"`
ScannedAt string `json:"scanned_at"`
Error string `json:"error,omitempty"`
// Incomplete lists checks that could not be completed (e.g. a timeout or
// rate limit while fetching a config). A non-empty slice means the findings
// are partial — the scan must not be read as a clean bill of health. Each
// entry is "<area>: <cause>".
Incomplete []string `json:"incomplete,omitempty"`
}
ScanResult holds the complete results for a repository scan
func (*ScanResult) CountBySeverity ¶
func (r *ScanResult) CountBySeverity() map[string]int
CountBySeverity returns counts for each severity level
func (*ScanResult) CountSuccesses ¶
func (r *ScanResult) CountSuccesses() int
type Scanner ¶
type Scanner struct {
// contains filtered or unexported fields
}
Scanner performs security checks on GitHub repositories
func NewWithToken ¶
NewWithToken creates a Scanner with an authenticated GitHub client
func (*Scanner) GitHubClient ¶
GitHubClient returns the underlying github.Client for use in batch operations such as listing repositories for a user or organization.
func (*Scanner) IsAuthenticated ¶
IsAuthenticated reports whether the scanner was constructed with a token.
func (*Scanner) ScanRepoWithOptions ¶
func (s *Scanner) ScanRepoWithOptions(ctx context.Context, owner, repo string, opts ScanOptions) (*ScanResult, error)
type UpdateToolConfigurationRuleOptions ¶
type UpdateToolConfigurationRuleOptions struct {
RequireWorkflows bool `yaml:"require_workflows"`
}
type WorkflowFact ¶
type WorkflowFact struct {
Path string
Content string
Workflow *WorkflowFile
Valid bool
}
type WorkflowFile ¶
type WorkflowFile struct {
Name string `yaml:"name"`
On interface{} `yaml:"on"` // Can be string, []string, or map
Permissions interface{} `yaml:"permissions"`
Jobs map[string]WorkflowJob `yaml:"jobs"`
}
WorkflowFile represents a parsed GitHub Actions workflow
type WorkflowJob ¶
type WorkflowJob struct {
Name string `yaml:"name"`
Permissions interface{} `yaml:"permissions"`
Steps []WorkflowStep `yaml:"steps"`
RunsOn interface{} `yaml:"runs-on"`
Uses string `yaml:"uses"` // For reusable workflows
Env map[string]string `yaml:"env"`
}
WorkflowJob represents a job in a workflow