mirror of
https://github.com/anthropics/claude-code-action.git
synced 2026-01-22 22:44:13 +08:00
chore: bump Claude Code version to 1.0.108
This commit is contained in:
committed by
Ashwin Bhat
parent
1a8e7d330a
commit
374c1885f1
1
.github/workflows/issue-triage.yml
vendored
1
.github/workflows/issue-triage.yml
vendored
@@ -102,6 +102,7 @@ jobs:
|
||||
prompt: $(cat /tmp/claude-prompts/triage-prompt.txt)
|
||||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
allowed_non_write_users: "*"
|
||||
claude_args: |
|
||||
--allowedTools Bash(gh label list),mcp__github__get_issue,mcp__github__get_issue_comments,mcp__github__update_issue,mcp__github__search_issues,mcp__github__list_issues
|
||||
--mcp-config /tmp/mcp-config/mcp-servers.json
|
||||
|
||||
@@ -27,6 +27,10 @@ inputs:
|
||||
description: "Comma-separated list of allowed bot usernames, or '*' to allow all bots. Empty string (default) allows no bots."
|
||||
required: false
|
||||
default: ""
|
||||
allowed_non_write_users:
|
||||
description: "Comma-separated list of usernames to allow without write permissions, or '*' to allow all users. Only works when github_token input is provided. WARNING: Use with extreme caution - this bypasses security checks and should only be used for workflows with very limited permissions (e.g., issue labeling)."
|
||||
required: false
|
||||
default: ""
|
||||
|
||||
# Claude Code configuration
|
||||
prompt:
|
||||
@@ -148,6 +152,7 @@ runs:
|
||||
BRANCH_PREFIX: ${{ inputs.branch_prefix }}
|
||||
OVERRIDE_GITHUB_TOKEN: ${{ inputs.github_token }}
|
||||
ALLOWED_BOTS: ${{ inputs.allowed_bots }}
|
||||
ALLOWED_NON_WRITE_USERS: ${{ inputs.allowed_non_write_users }}
|
||||
GITHUB_RUN_ID: ${{ github.run_id }}
|
||||
USE_STICKY_COMMENT: ${{ inputs.use_sticky_comment }}
|
||||
DEFAULT_WORKFLOW_TOKEN: ${{ github.token }}
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
|
||||
- **Repository Access**: The action can only be triggered by users with write access to the repository
|
||||
- **Bot User Control**: By default, GitHub Apps and bots cannot trigger this action for security reasons. Use the `allowed_bots` parameter to enable specific bots or all bots
|
||||
- **⚠️ Non-Write User Access (RISKY)**: The `allowed_non_write_users` parameter allows bypassing the write permission requirement. **This is a significant security risk and should only be used for workflows with extremely limited permissions** (e.g., issue labeling workflows that only have `issues: write` permission). This feature:
|
||||
- Only works when `github_token` is provided as input (not with GitHub App authentication)
|
||||
- Accepts either a comma-separated list of specific usernames or `*` to allow all users
|
||||
- **Should be used with extreme caution** as it bypasses the primary security mechanism of this action
|
||||
- Is designed for automation workflows where user permissions are already restricted by the workflow's permission scope
|
||||
- **Token Permissions**: The GitHub app receives only a short-lived token scoped specifically to the repository it's operating in
|
||||
- **No Cross-Repository Access**: Each action invocation is limited to the repository where it was triggered
|
||||
- **Limited Scope**: The token cannot access other repositories or perform actions beyond the configured permissions
|
||||
|
||||
@@ -48,7 +48,7 @@ jobs:
|
||||
## Inputs
|
||||
|
||||
| Input | Description | Required | Default |
|
||||
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------- | -------- | ------------- |
|
||||
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- | ------------- |
|
||||
| `anthropic_api_key` | Anthropic API key (required for direct API, not needed for Bedrock/Vertex) | No\* | - |
|
||||
| `claude_code_oauth_token` | Claude Code OAuth token (alternative to anthropic_api_key) | No\* | - |
|
||||
| `prompt` | Instructions for Claude. Can be a direct prompt or custom template for automation workflows | No | - |
|
||||
@@ -71,6 +71,7 @@ jobs:
|
||||
| `bot_id` | GitHub user ID to use for git operations (defaults to Claude's bot ID) | No | `41898282` |
|
||||
| `bot_name` | GitHub username to use for git operations (defaults to Claude's bot name) | No | `claude[bot]` |
|
||||
| `allowed_bots` | Comma-separated list of allowed bot usernames, or '\*' to allow all bots. Empty string (default) allows no bots | No | "" |
|
||||
| `allowed_non_write_users` | **⚠️ RISKY**: Comma-separated list of usernames to allow without write permissions, or '\*' for all users. Only works with `github_token` input. See [Security](./security.md) | No | "" |
|
||||
|
||||
### Deprecated Inputs
|
||||
|
||||
|
||||
@@ -30,9 +30,13 @@ async function run() {
|
||||
|
||||
// Step 3: Check write permissions (only for entity contexts)
|
||||
if (isEntityContext(context)) {
|
||||
// Check if github_token was provided as input (not from app)
|
||||
const githubTokenProvided = !!process.env.OVERRIDE_GITHUB_TOKEN;
|
||||
const hasWritePermissions = await checkWritePermissions(
|
||||
octokit.rest,
|
||||
context,
|
||||
context.inputs.allowedNonWriteUsers,
|
||||
githubTokenProvided,
|
||||
);
|
||||
if (!hasWritePermissions) {
|
||||
throw new Error(
|
||||
|
||||
@@ -93,6 +93,7 @@ type BaseContext = {
|
||||
botId: string;
|
||||
botName: string;
|
||||
allowedBots: string;
|
||||
allowedNonWriteUsers: string;
|
||||
trackProgress: boolean;
|
||||
};
|
||||
};
|
||||
@@ -147,6 +148,7 @@ export function parseGitHubContext(): GitHubContext {
|
||||
botId: process.env.BOT_ID ?? String(CLAUDE_APP_BOT_ID),
|
||||
botName: process.env.BOT_NAME ?? CLAUDE_BOT_LOGIN,
|
||||
allowedBots: process.env.ALLOWED_BOTS ?? "",
|
||||
allowedNonWriteUsers: process.env.ALLOWED_NON_WRITE_USERS ?? "",
|
||||
trackProgress: process.env.TRACK_PROGRESS === "true",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -6,17 +6,43 @@ import type { Octokit } from "@octokit/rest";
|
||||
* Check if the actor has write permissions to the repository
|
||||
* @param octokit - The Octokit REST client
|
||||
* @param context - The GitHub context
|
||||
* @param allowedNonWriteUsers - Comma-separated list of users allowed without write permissions, or '*' for all
|
||||
* @param githubTokenProvided - Whether github_token was provided as input (not from app)
|
||||
* @returns true if the actor has write permissions, false otherwise
|
||||
*/
|
||||
export async function checkWritePermissions(
|
||||
octokit: Octokit,
|
||||
context: ParsedGitHubContext,
|
||||
allowedNonWriteUsers?: string,
|
||||
githubTokenProvided?: boolean,
|
||||
): Promise<boolean> {
|
||||
const { repository, actor } = context;
|
||||
|
||||
try {
|
||||
core.info(`Checking permissions for actor: ${actor}`);
|
||||
|
||||
// Check if we should bypass permission checks for this user
|
||||
if (allowedNonWriteUsers && githubTokenProvided) {
|
||||
const allowedUsers = allowedNonWriteUsers.trim();
|
||||
if (allowedUsers === "*") {
|
||||
core.warning(
|
||||
`⚠️ SECURITY WARNING: Bypassing write permission check for ${actor} due to allowed_non_write_users='*'. This should only be used for workflows with very limited permissions.`,
|
||||
);
|
||||
return true;
|
||||
} else if (allowedUsers) {
|
||||
const allowedUserList = allowedUsers
|
||||
.split(",")
|
||||
.map((u) => u.trim())
|
||||
.filter((u) => u.length > 0);
|
||||
if (allowedUserList.includes(actor)) {
|
||||
core.warning(
|
||||
`⚠️ SECURITY WARNING: Bypassing write permission check for ${actor} due to allowed_non_write_users configuration. This should only be used for workflows with very limited permissions.`,
|
||||
);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the actor is a GitHub App (bot user)
|
||||
if (actor.endsWith("[bot]")) {
|
||||
core.info(`Actor is a GitHub App: ${actor}`);
|
||||
|
||||
@@ -35,6 +35,7 @@ describe("prepareMcpConfig", () => {
|
||||
botId: String(CLAUDE_APP_BOT_ID),
|
||||
botName: CLAUDE_BOT_LOGIN,
|
||||
allowedBots: "",
|
||||
allowedNonWriteUsers: "",
|
||||
trackProgress: false,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -23,6 +23,7 @@ const defaultInputs = {
|
||||
botId: String(CLAUDE_APP_BOT_ID),
|
||||
botName: CLAUDE_BOT_LOGIN,
|
||||
allowedBots: "",
|
||||
allowedNonWriteUsers: "",
|
||||
trackProgress: false,
|
||||
};
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@ describe("checkWritePermissions", () => {
|
||||
botId: String(CLAUDE_APP_BOT_ID),
|
||||
botName: CLAUDE_BOT_LOGIN,
|
||||
allowedBots: "",
|
||||
allowedNonWriteUsers: "",
|
||||
trackProgress: false,
|
||||
},
|
||||
});
|
||||
@@ -175,4 +176,126 @@ describe("checkWritePermissions", () => {
|
||||
username: "test-user",
|
||||
});
|
||||
});
|
||||
|
||||
describe("allowed_non_write_users bypass", () => {
|
||||
test("should bypass permission check for specific user when github_token provided", async () => {
|
||||
const mockOctokit = createMockOctokit("read");
|
||||
const context = createContext();
|
||||
|
||||
const result = await checkWritePermissions(
|
||||
mockOctokit,
|
||||
context,
|
||||
"test-user,other-user",
|
||||
true,
|
||||
);
|
||||
|
||||
expect(result).toBe(true);
|
||||
expect(coreWarningSpy).toHaveBeenCalledWith(
|
||||
"⚠️ SECURITY WARNING: Bypassing write permission check for test-user due to allowed_non_write_users configuration. This should only be used for workflows with very limited permissions.",
|
||||
);
|
||||
});
|
||||
|
||||
test("should bypass permission check for all users with wildcard", async () => {
|
||||
const mockOctokit = createMockOctokit("read");
|
||||
const context = createContext();
|
||||
|
||||
const result = await checkWritePermissions(
|
||||
mockOctokit,
|
||||
context,
|
||||
"*",
|
||||
true,
|
||||
);
|
||||
|
||||
expect(result).toBe(true);
|
||||
expect(coreWarningSpy).toHaveBeenCalledWith(
|
||||
"⚠️ SECURITY WARNING: Bypassing write permission check for test-user due to allowed_non_write_users='*'. This should only be used for workflows with very limited permissions.",
|
||||
);
|
||||
});
|
||||
|
||||
test("should NOT bypass permission check when user not in allowed list", async () => {
|
||||
const mockOctokit = createMockOctokit("read");
|
||||
const context = createContext();
|
||||
|
||||
const result = await checkWritePermissions(
|
||||
mockOctokit,
|
||||
context,
|
||||
"other-user,another-user",
|
||||
true,
|
||||
);
|
||||
|
||||
expect(result).toBe(false);
|
||||
expect(coreWarningSpy).toHaveBeenCalledWith(
|
||||
"Actor has insufficient permissions: read",
|
||||
);
|
||||
});
|
||||
|
||||
test("should NOT bypass permission check when github_token not provided", async () => {
|
||||
const mockOctokit = createMockOctokit("read");
|
||||
const context = createContext();
|
||||
|
||||
const result = await checkWritePermissions(
|
||||
mockOctokit,
|
||||
context,
|
||||
"test-user",
|
||||
false,
|
||||
);
|
||||
|
||||
expect(result).toBe(false);
|
||||
expect(coreWarningSpy).toHaveBeenCalledWith(
|
||||
"Actor has insufficient permissions: read",
|
||||
);
|
||||
});
|
||||
|
||||
test("should NOT bypass permission check when allowed_non_write_users is empty", async () => {
|
||||
const mockOctokit = createMockOctokit("read");
|
||||
const context = createContext();
|
||||
|
||||
const result = await checkWritePermissions(
|
||||
mockOctokit,
|
||||
context,
|
||||
"",
|
||||
true,
|
||||
);
|
||||
|
||||
expect(result).toBe(false);
|
||||
expect(coreWarningSpy).toHaveBeenCalledWith(
|
||||
"Actor has insufficient permissions: read",
|
||||
);
|
||||
});
|
||||
|
||||
test("should handle whitespace in allowed_non_write_users list", async () => {
|
||||
const mockOctokit = createMockOctokit("read");
|
||||
const context = createContext();
|
||||
|
||||
const result = await checkWritePermissions(
|
||||
mockOctokit,
|
||||
context,
|
||||
" test-user , other-user ",
|
||||
true,
|
||||
);
|
||||
|
||||
expect(result).toBe(true);
|
||||
expect(coreWarningSpy).toHaveBeenCalledWith(
|
||||
"⚠️ SECURITY WARNING: Bypassing write permission check for test-user due to allowed_non_write_users configuration. This should only be used for workflows with very limited permissions.",
|
||||
);
|
||||
});
|
||||
|
||||
test("should bypass for bot users even when allowed_non_write_users is set", async () => {
|
||||
const mockOctokit = createMockOctokit("none");
|
||||
const context = createContext();
|
||||
context.actor = "test-bot[bot]";
|
||||
|
||||
const result = await checkWritePermissions(
|
||||
mockOctokit,
|
||||
context,
|
||||
"some-user",
|
||||
true,
|
||||
);
|
||||
|
||||
expect(result).toBe(true);
|
||||
expect(coreInfoSpy).toHaveBeenCalledWith(
|
||||
"Actor is a GitHub App: test-bot[bot]",
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user