Skip to content

chore: adjust activity alerts for allowed domains and accounts#15343

Merged
mnkiefer merged 2 commits intomainfrom
add-allowed-lists
Feb 13, 2026
Merged

chore: adjust activity alerts for allowed domains and accounts#15343
mnkiefer merged 2 commits intomainfrom
add-allowed-lists

Conversation

@mnkiefer
Copy link
Contributor

  • Adds explicit allowlists for domains, accounts, and organizations, dynamically loading repository and organization members, and refining the reporting output for better clarity.

@mnkiefer mnkiefer self-assigned this Feb 13, 2026
Copilot AI review requested due to automatic review settings February 13, 2026 08:02
@mnkiefer mnkiefer changed the title chore: adjust activity detection for allowed domains and accounts chore: adjust activity alerts for allowed domains and accounts Feb 13, 2026
@mnkiefer mnkiefer merged commit ffb762c into main Feb 13, 2026
47 of 48 checks passed
@mnkiefer mnkiefer deleted the add-allowed-lists branch February 13, 2026 08:02
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enhances the bot detection workflow by adding explicit allowlists for trusted domains, accounts, and organizations. It dynamically loads repository collaborators and organization members to reduce false positives, and improves the reporting output by embedding evidence per-account and showing which logins are associated with each external domain.

Changes:

  • Adds allowlists for trusted domains (GitHub docs, package registries, language vendor sites), accounts (bots, service accounts), and organizations with dynamic member loading
  • Introduces environment variable support for extending allowlists via BOT_DETECTION_ALLOWED_DOMAINS, BOT_DETECTION_ALLOWED_ACCOUNTS, and BOT_DETECTION_TRUSTED_ORGS
  • Refactors reporting to show login examples in the domains table and embed evidence details per-account instead of in a separate section

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.

File Description
.github/workflows/bot-detection.md Adds allowlist constants, dynamic member loading functions, integrates allowlist checks throughout the analysis flow, and updates the report format
.github/workflows/bot-detection.lock.yml Compiled version of the .md file changes with identical logic updates

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 320 to +321
if (login) {
if (isAllowedAccount(login)) continue;
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This continue statement causes the entire PR to be skipped when the PR author is an allowed account. This means comments and reviews on that PR (which may come from suspicious accounts) are never analyzed. The continue should be removed, and only the ensureUserCreatedAt call on line 322 should be skipped for allowed accounts.

Suggested change
if (login) {
if (isAllowedAccount(login)) continue;
if (login && !isAllowedAccount(login)) {

Copilot uses AI. Check for mistakes.
Comment on lines +143 to +153
for (const org of TRUSTED_ORGS) {
try {
const members = await github.paginate(github.rest.orgs.listMembers, {
org,
per_page: 100,
});
for (const member of members) {
if (member?.login) {
MEMBER_ACCOUNTS.add(String(member.login).toLowerCase());
}
}
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The github.paginate call for org members lacks a cap. For large organizations like "github", this could fetch thousands of members. Consider adding pagination caps similar to other paginate calls in this file (lines 328-350, 358-380, 388-410, 464-486) that use a response callback with a cap of 500 items.

Suggested change
for (const org of TRUSTED_ORGS) {
try {
const members = await github.paginate(github.rest.orgs.listMembers, {
org,
per_page: 100,
});
for (const member of members) {
if (member?.login) {
MEMBER_ACCOUNTS.add(String(member.login).toLowerCase());
}
}
const MAX_ORG_MEMBERS = 500;
for (const org of TRUSTED_ORGS) {
let fetchedForOrg = 0;
try {
await github.paginate(
github.rest.orgs.listMembers,
{
org,
per_page: 100,
},
(response, done) => {
for (const member of response.data || []) {
if (member?.login) {
MEMBER_ACCOUNTS.add(String(member.login).toLowerCase());
fetchedForOrg++;
if (fetchedForOrg >= MAX_ORG_MEMBERS) {
done();
break;
}
}
}
// We process members directly; no need to accumulate return values.
return [];
}
);

Copilot uses AI. Check for mistakes.
Comment on lines +127 to +136
const collaborators = await github.paginate(github.rest.repos.listCollaborators, {
owner,
repo,
per_page: 100,
});
for (const collaborator of collaborators) {
if (collaborator?.login) {
MEMBER_ACCOUNTS.add(String(collaborator.login).toLowerCase());
}
}
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The github.paginate call for collaborators lacks a cap. For repositories with many collaborators, this could fetch a large number of items without limit. Consider adding pagination caps similar to other paginate calls in this file that use a response callback with a cap of 500 items.

Suggested change
const collaborators = await github.paginate(github.rest.repos.listCollaborators, {
owner,
repo,
per_page: 100,
});
for (const collaborator of collaborators) {
if (collaborator?.login) {
MEMBER_ACCOUNTS.add(String(collaborator.login).toLowerCase());
}
}
let count = 0;
await github.paginate(
github.rest.repos.listCollaborators,
{
owner,
repo,
per_page: 100,
},
(response, done) => {
for (const collaborator of response.data) {
if (count >= 500) {
done();
break;
}
if (collaborator?.login) {
MEMBER_ACCOUNTS.add(String(collaborator.login).toLowerCase());
count++;
}
}
// We only use side effects on MEMBER_ACCOUNTS; no need to return data.
return [];
}
);

Copilot uses AI. Check for mistakes.
for (const it of prItems) {
const login = it.author;
if (login) {
if (isAllowedAccount(login)) continue;
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This continue statement causes the entire PR to be skipped when the PR author is an allowed account. This means comments and reviews on that PR (which may come from suspicious accounts) are never analyzed. The continue should be removed, and only the ensureUserCreatedAt call on line 1295 should be skipped for allowed accounts.

See below for a potential fix:

              if (login && !isAllowedAccount(login)) {
                await ensureUserCreatedAt(login);
              }

              let issueComments = [];
              try {
              try {

Copilot uses AI. Check for mistakes.
Comment on lines +1118 to +1121
const members = await github.paginate(github.rest.orgs.listMembers, {
org,
per_page: 100,
});
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The github.paginate call for org members lacks a cap. For large organizations like "github", this could fetch thousands of members. Consider adding pagination caps similar to other paginate calls in this file (lines 1100-1104, 1118-1121) that use a response callback with a cap of 500 items.

Suggested change
const members = await github.paginate(github.rest.orgs.listMembers, {
org,
per_page: 100,
});
let memberCount = 0;
const members = await github.paginate(
github.rest.orgs.listMembers,
{
org,
per_page: 100,
},
(response, done) => {
const remaining = 500 - memberCount;
if (remaining <= 0) {
done();
return [];
}
const pageItems = response.data.slice(0, remaining);
memberCount += pageItems.length;
if (memberCount >= 500) {
done();
}
return pageItems;
}
);

Copilot uses AI. Check for mistakes.
Comment on lines +1099 to +1104
try {
const collaborators = await github.paginate(github.rest.repos.listCollaborators, {
owner,
repo,
per_page: 100,
});
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The github.paginate call for collaborators lacks a cap. For repositories with many collaborators, this could fetch a large number of items without limit. Consider adding pagination caps similar to other paginate calls in this file that use a response callback with a cap of 500 items.

Suggested change
try {
const collaborators = await github.paginate(github.rest.repos.listCollaborators, {
owner,
repo,
per_page: 100,
});
let totalCollaborators = 0;
try {
const collaborators = await github.paginate(
github.rest.repos.listCollaborators,
{
owner,
repo,
per_page: 100,
},
(response, done) => {
const remaining = 500 - totalCollaborators;
if (remaining <= 0) {
done();
return [];
}
const pageItems = Array.isArray(response.data)
? response.data.slice(0, remaining)
: [];
totalCollaborators += pageItems.length;
if (totalCollaborators >= 500) {
done();
}
return pageItems;
}
);

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant