mirror of
https://github.com/anthropics/claude-code-action.git
synced 2026-01-23 06:54:13 +08:00
feat: add flexible bot access control with allowed_bots option (#117)
* feat: skip permission check for GitHub App bot users GitHub Apps (users ending with [bot]) now bypass permission checks as they have their own authorization mechanism. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * feat: add allow_bot_users option to control bot user access - Add allow_bot_users input parameter (default: false) - Modify checkHumanActor to optionally allow bot users - Add comprehensive tests for bot user handling - Improve security by blocking bot users by default This change prevents potential prompt injection attacks from bot users while providing flexibility for trusted bot integrations. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: mark bot user support feature as completed in roadmap 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: move allowedBots parameter to context object Move allowedBots from function parameter to context.inputs to maintain consistency with other input handling throughout the codebase. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: update README for bot user support feature Add documentation for the new allowed_bots parameter that enables bot users to trigger Claude actions with granular control. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: add missing allowedBots property in permissions test 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: update bot name format to include [bot] suffix in tests and docs - Update test cases to use correct bot actor names with [bot] suffix - Update documentation example to show correct bot name format - Align with GitHub's actual bot naming convention 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * feat: normalize bot names for allowed_bots validation - Strip [bot] suffix from both actor names and allowed bot list for comparison - Allow both "dependabot" and "dependabot[bot]" formats in allowed_bots input - Display normalized bot names in error messages for consistency - Add comprehensive test coverage for both naming formats 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -77,6 +77,7 @@ type BaseContext = {
|
||||
useStickyComment: boolean;
|
||||
additionalPermissions: Map<string, string>;
|
||||
useCommitSigning: boolean;
|
||||
allowedBots: string;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -136,6 +137,7 @@ export function parseGitHubContext(): GitHubContext {
|
||||
process.env.ADDITIONAL_PERMISSIONS ?? "",
|
||||
),
|
||||
useCommitSigning: process.env.USE_COMMIT_SIGNING === "true",
|
||||
allowedBots: process.env.ALLOWED_BOTS ?? "",
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -21,9 +21,42 @@ export async function checkHumanActor(
|
||||
|
||||
console.log(`Actor type: ${actorType}`);
|
||||
|
||||
// Check bot permissions if actor is not a User
|
||||
if (actorType !== "User") {
|
||||
const allowedBots = githubContext.inputs.allowedBots;
|
||||
|
||||
// Check if all bots are allowed
|
||||
if (allowedBots.trim() === "*") {
|
||||
console.log(
|
||||
`All bots are allowed, skipping human actor check for: ${githubContext.actor}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse allowed bots list
|
||||
const allowedBotsList = allowedBots
|
||||
.split(",")
|
||||
.map((bot) =>
|
||||
bot
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
.replace(/\[bot\]$/, ""),
|
||||
)
|
||||
.filter((bot) => bot.length > 0);
|
||||
|
||||
const botName = githubContext.actor.toLowerCase().replace(/\[bot\]$/, "");
|
||||
|
||||
// Check if specific bot is allowed
|
||||
if (allowedBotsList.includes(botName)) {
|
||||
console.log(
|
||||
`Bot ${botName} is in allowed list, skipping human actor check`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Bot not allowed
|
||||
throw new Error(
|
||||
`Workflow initiated by non-human actor: ${githubContext.actor} (type: ${actorType}).`,
|
||||
`Workflow initiated by non-human actor: ${botName} (type: ${actorType}). Add bot to allowed_bots list or use '*' to allow all bots.`,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,12 @@ export async function checkWritePermissions(
|
||||
try {
|
||||
core.info(`Checking permissions for actor: ${actor}`);
|
||||
|
||||
// Check if the actor is a GitHub App (bot user)
|
||||
if (actor.endsWith("[bot]")) {
|
||||
core.info(`Actor is a GitHub App: ${actor}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check permissions directly using the permission endpoint
|
||||
const response = await octokit.repos.getCollaboratorPermissionLevel({
|
||||
owner: repository.owner,
|
||||
|
||||
Reference in New Issue
Block a user