@@ -60,6 +60,8 @@ func (l *DependabotPlugin) Eval(req *proto.EvalRequest, apiHelper runner.ApiHelp
6060 }
6161
6262 done := false
63+ // Track permission issues during alert collection
64+ reposAlertsPermissionDenied := make ([]string , 0 )
6365
6466 for ! done {
6567 select {
@@ -79,6 +81,11 @@ func (l *DependabotPlugin) Eval(req *proto.EvalRequest, apiHelper runner.ApiHelp
7981
8082 alerts , err := l .FetchRepositoryDependabotAlerts (ctx , repo )
8183 if err != nil {
84+ if isPermissionError (err ) {
85+ l .logger .Warn ("Skipping repository due to insufficient permissions for alerts fetch" , "repo" , repo .GetFullName (), "error" , err )
86+ reposAlertsPermissionDenied = append (reposAlertsPermissionDenied , repo .GetFullName ())
87+ continue
88+ }
8289 return & proto.EvalResponse {
8390 Status : proto .ExecutionStatus_FAILURE ,
8491 }, err
@@ -107,6 +114,10 @@ func (l *DependabotPlugin) Eval(req *proto.EvalRequest, apiHelper runner.ApiHelp
107114 }
108115 }
109116
117+ if len (reposAlertsPermissionDenied ) > 0 {
118+ l .logger .Info ("Repositories skipped due to insufficient permissions (alerts)" , "count" , len (reposAlertsPermissionDenied ), "repos" , reposAlertsPermissionDenied )
119+ }
120+
110121 return & proto.EvalResponse {
111122 Status : proto .ExecutionStatus_SUCCESS ,
112123 }, nil
@@ -124,7 +135,7 @@ func (l *DependabotPlugin) FetchRepositoryDependabotAlerts(ctx context.Context,
124135 alerts , _ , err := l .githubClient .Dependabot .ListRepoAlerts (ctx , repo .GetOwner ().GetLogin (), repo .GetName (), & github.ListAlertsOptions {
125136 ListOptions : github.ListOptions {
126137 Page : 1 ,
127- PerPage : 200 ,
138+ PerPage : 100 ,
128139 },
129140 ListCursorOptions : github.ListCursorOptions {},
130141 })
@@ -139,6 +150,10 @@ func (l *DependabotPlugin) FetchRepositories(ctx context.Context) (<-chan *githu
139150 defer close (errs )
140151 page := 1
141152 done := false
153+ // Tracking for logging visibility
154+ emittedRepos := make ([]string , 0 )
155+ noPermissionRepos := make ([]string , 0 )
156+ archivedSkipped := 0
142157 for ! done {
143158 l .logger .Trace ("Fetching repositories from Github API" )
144159 repos , _ , err := l .githubClient .Repositories .ListByOrg (ctx , * l .config .Organization , & github.RepositoryListByOrgOptions {
@@ -153,14 +168,25 @@ func (l *DependabotPlugin) FetchRepositories(ctx context.Context) (<-chan *githu
153168 break
154169 }
155170 for _ , repo := range repos {
171+ if repo .GetArchived () {
172+ archivedSkipped ++
173+ continue
174+ }
175+
156176 alertsEnabled , _ , err := l .githubClient .Repositories .GetVulnerabilityAlerts (ctx , repo .GetOwner ().GetLogin (), repo .GetName ())
157177 if err != nil {
178+ if isPermissionError (err ) {
179+ l .logger .Warn ("Skipping repository due to insufficient permissions for vulnerability alerts check" , "repo" , repo .GetFullName (), "error" , err )
180+ noPermissionRepos = append (noPermissionRepos , repo .GetFullName ())
181+ continue
182+ }
158183 errs <- err
159184 done = true
160185 break
161186 }
162- if ! repo . GetArchived () && alertsEnabled {
187+ if alertsEnabled {
163188 repositories <- repo
189+ emittedRepos = append (emittedRepos , repo .GetFullName ())
164190 }
165191 }
166192 page ++
@@ -169,6 +195,14 @@ func (l *DependabotPlugin) FetchRepositories(ctx context.Context) (<-chan *githu
169195 break
170196 }
171197 }
198+ // Emit a summary for engineers to understand visibility
199+ l .logger .Info ("Repository enumeration summary" , "emitted" , len (emittedRepos ), "skipped_permissions" , len (noPermissionRepos ), "skipped_archived" , archivedSkipped )
200+ if len (emittedRepos ) > 0 {
201+ l .logger .Debug ("Repositories with sufficient permissions (and alerts enabled)" , "repos" , emittedRepos )
202+ }
203+ if len (noPermissionRepos ) > 0 {
204+ l .logger .Info ("Repositories without sufficient permissions" , "repos" , noPermissionRepos )
205+ }
172206 }()
173207 return repositories , errs
174208}
@@ -195,13 +229,13 @@ func (l *DependabotPlugin) EvaluatePolicies(ctx context.Context, repo *github.Re
195229 Props : nil ,
196230 },
197231 {
198- Title : "Continuous Compliance Framework - Local SSH Plugin" ,
232+ Title : "Continuous Compliance Framework - Dependabot Plugin" ,
199233 Type : "tool" ,
200234 Links : []* proto.Link {
201235 {
202- Href : "https://github.com/compliance-framework/plugin-local-ssh " ,
236+ Href : "https://github.com/compliance-framework/plugin-dependabot " ,
203237 Rel : policyManager .Pointer ("reference" ),
204- Text : policyManager .Pointer ("The Continuous Compliance Framework' Local SSH Plugin" ),
238+ Text : policyManager .Pointer ("The Continuous Compliance Framework Dependabot Plugin" ),
205239 },
206240 },
207241 Props : nil ,
@@ -305,6 +339,24 @@ func (l *DependabotPlugin) EvaluatePolicies(ctx context.Context, repo *github.Re
305339 return evidences , accumulatedErrors
306340}
307341
342+ // isPermissionError returns true if the error from the GitHub client indicates
343+ // a permissions or visibility issue (e.g., 401/403/404).
344+ func isPermissionError (err error ) bool {
345+ if err == nil {
346+ return false
347+ }
348+ var ger * github.ErrorResponse
349+ if errors .As (err , & ger ) {
350+ if ger .Response != nil {
351+ switch ger .Response .StatusCode {
352+ case 401 , 403 , 404 :
353+ return true
354+ }
355+ }
356+ }
357+ return false
358+ }
359+
308360func main () {
309361 logger := hclog .New (& hclog.LoggerOptions {
310362 Level : hclog .Debug ,
0 commit comments