Skip to content

Commit 869c024

Browse files
committed
Dont filter content from trusted bots
1 parent 2941e87 commit 869c024

File tree

2 files changed

+41
-13
lines changed

2 files changed

+41
-13
lines changed

pkg/lockdown/lockdown.go

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,27 @@ import (
1515
// RepoAccessCache caches repository metadata related to lockdown checks so that
1616
// multiple tools can reuse the same access information safely across goroutines.
1717
type RepoAccessCache struct {
18-
client *githubv4.Client
19-
mu sync.Mutex
20-
cache *cache2go.CacheTable
21-
ttl time.Duration
22-
logger *slog.Logger
18+
client *githubv4.Client
19+
mu sync.Mutex
20+
cache *cache2go.CacheTable
21+
ttl time.Duration
22+
logger *slog.Logger
23+
trustedBotLogins map[string]struct{}
2324
}
2425

2526
type repoAccessCacheEntry struct {
2627
isPrivate bool
2728
knownUsers map[string]bool // normalized login -> has push access
2829
viewerLogin string
30+
viewerType string
2931
}
3032

3133
// RepoAccessInfo captures repository metadata needed for lockdown decisions.
3234
type RepoAccessInfo struct {
3335
IsPrivate bool
3436
HasPushAccess bool
3537
ViewerLogin string
38+
ViewerType string
3639
}
3740

3841
const (
@@ -85,6 +88,12 @@ func GetInstance(client *githubv4.Client, opts ...RepoAccessOption) *RepoAccessC
8588
client: client,
8689
cache: cache2go.Cache(defaultRepoAccessCacheKey),
8790
ttl: defaultRepoAccessTTL,
91+
trustedBotLogins: map[string]struct{}{
92+
"dependabot[bot]": {},
93+
"dependabot-preview[bot]": {},
94+
"github-actions[bot]": {},
95+
"github-copilot[bot]": {},
96+
},
8897
}
8998
for _, opt := range opts {
9099
if opt != nil {
@@ -115,7 +124,8 @@ func (c *RepoAccessCache) IsSafeContent(ctx context.Context, username, owner, re
115124
c.logDebug("error checking repo access info for content filtering", "owner", owner, "repo", repo, "user", username, "error", err)
116125
return false, err
117126
}
118-
if repoInfo.IsPrivate || repoInfo.ViewerLogin == username {
127+
128+
if c.isTrustedBot(username, repoInfo.ViewerType) || repoInfo.IsPrivate || repoInfo.ViewerLogin == username {
119129
return true, nil
120130
}
121131
return repoInfo.HasPushAccess, nil
@@ -150,12 +160,14 @@ func (c *RepoAccessCache) getRepoAccessInfo(ctx context.Context, username, owner
150160
}
151161
entry.knownUsers[userKey] = info.HasPushAccess
152162
entry.viewerLogin = info.ViewerLogin
163+
entry.viewerType = info.ViewerType
153164
entry.isPrivate = info.IsPrivate
154165
c.cache.Add(key, c.ttl, entry)
155166
return RepoAccessInfo{
156167
IsPrivate: entry.isPrivate,
157168
HasPushAccess: entry.knownUsers[userKey],
158169
ViewerLogin: entry.viewerLogin,
170+
ViewerType: entry.viewerType,
159171
}, nil
160172
}
161173

@@ -171,13 +183,15 @@ func (c *RepoAccessCache) getRepoAccessInfo(ctx context.Context, username, owner
171183
knownUsers: map[string]bool{userKey: info.HasPushAccess},
172184
isPrivate: info.IsPrivate,
173185
viewerLogin: info.ViewerLogin,
186+
viewerType: info.ViewerType,
174187
}
175188
c.cache.Add(key, c.ttl, entry)
176189

177190
return RepoAccessInfo{
178191
IsPrivate: entry.isPrivate,
179192
HasPushAccess: entry.knownUsers[userKey],
180193
ViewerLogin: entry.viewerLogin,
194+
ViewerType: entry.viewerType,
181195
}, nil
182196
}
183197

@@ -188,7 +202,8 @@ func (c *RepoAccessCache) queryRepoAccessInfo(ctx context.Context, username, own
188202

189203
var query struct {
190204
Viewer struct {
191-
Login githubv4.String
205+
Typename string `graphql:"__typename"`
206+
Login githubv4.String
192207
}
193208
Repository struct {
194209
IsPrivate githubv4.Boolean
@@ -227,15 +242,24 @@ func (c *RepoAccessCache) queryRepoAccessInfo(ctx context.Context, username, own
227242
IsPrivate: bool(query.Repository.IsPrivate),
228243
HasPushAccess: hasPush,
229244
ViewerLogin: string(query.Viewer.Login),
245+
ViewerType: query.Viewer.Typename,
230246
}, nil
231247
}
232248

233-
func cacheKey(owner, repo string) string {
234-
return fmt.Sprintf("%s/%s", strings.ToLower(owner), strings.ToLower(repo))
235-
}
236-
237249
func (c *RepoAccessCache) logDebug(msg string, args ...any) {
238250
if c != nil && c.logger != nil {
239251
c.logger.Debug(msg, args...)
240252
}
241253
}
254+
255+
func (c *RepoAccessCache) isTrustedBot(username string, viewerType string) bool {
256+
if viewerType != "Bot" {
257+
return false
258+
}
259+
_, ok := c.trustedBotLogins[strings.ToLower(username)]
260+
return ok
261+
}
262+
263+
func cacheKey(owner, repo string) string {
264+
return fmt.Sprintf("%s/%s", strings.ToLower(owner), strings.ToLower(repo))
265+
}

pkg/lockdown/lockdown_test.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ const (
1919

2020
type repoAccessQuery struct {
2121
Viewer struct {
22-
Login githubv4.String
22+
Typename string `graphql:"__typename"`
23+
Login githubv4.String
2324
}
2425
Repository struct {
2526
IsPrivate githubv4.Boolean
@@ -66,7 +67,8 @@ func newMockRepoAccessCache(t *testing.T, ttl time.Duration) (*RepoAccessCache,
6667

6768
response := githubv4mock.DataResponse(map[string]any{
6869
"viewer": map[string]any{
69-
"login": testUser,
70+
"__typename": "User",
71+
"login": testUser,
7072
},
7173
"repository": map[string]any{
7274
"isPrivate": false,
@@ -99,6 +101,7 @@ func TestRepoAccessCacheEvictsAfterTTL(t *testing.T) {
99101
info, err := cache.getRepoAccessInfo(ctx, testUser, testOwner, testRepo)
100102
require.NoError(t, err)
101103
require.Equal(t, testUser, info.ViewerLogin)
104+
require.Equal(t, "User", info.ViewerType)
102105
require.True(t, info.HasPushAccess)
103106
require.EqualValues(t, 1, transport.CallCount())
104107

@@ -107,6 +110,7 @@ func TestRepoAccessCacheEvictsAfterTTL(t *testing.T) {
107110
info, err = cache.getRepoAccessInfo(ctx, testUser, testOwner, testRepo)
108111
require.NoError(t, err)
109112
require.Equal(t, testUser, info.ViewerLogin)
113+
require.Equal(t, "User", info.ViewerType)
110114
require.True(t, info.HasPushAccess)
111115
require.EqualValues(t, 2, transport.CallCount())
112116
}

0 commit comments

Comments
 (0)