From c93e8fe8795d6de1ce8b936330d35a0c2440cd96 Mon Sep 17 00:00:00 2001 From: Octavian Guzu Date: Tue, 28 Apr 2026 18:01:48 +0100 Subject: [PATCH] docs: pull_request_target guidance and base-action trust model (#1250) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: add pull_request_target/workflow_run guidance and base-action trust model Adds a security.md section on safe checkout patterns under pull_request_target/workflow_run, and a trust-model section to the base-action README clarifying that callers are responsible for the working directory and prompt being trusted. :house: Remote-Dev: homespace * docs: refine PRT/workflow_run guidance — root checkout + workflow_run ref Second example now checks out the base ref at the workspace root before the head-ref subdirectory checkout (this action expects a git repo at the root). Adds the workflow_run ref form, drops the PRT-specific gh-pr-diff hint from the first example, and generalises the closing line to cover both event types. :house: Remote-Dev: homespace * docs: use actions/checkout@v6 in examples (consistency) :house: Remote-Dev: homespace --- base-action/README.md | 8 ++++++++ docs/security.md | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/base-action/README.md b/base-action/README.md index 495ebf6..fa750ba 100644 --- a/base-action/README.md +++ b/base-action/README.md @@ -4,6 +4,14 @@ This GitHub Action allows you to run [Claude Code](https://www.anthropic.com/cla For simply tagging @claude in issues and PRs out of the box, [check out the Claude Code action and GitHub app](https://github.com/anthropics/claude-code-action). +## Trust model + +This action is a thin wrapper that installs and runs Claude Code with the inputs you provide. It does **not** enforce any trust boundaries on its own. Running this action in a directory is equivalent to running Claude Code in that directory — Claude reads project-level configuration (`.claude/`, `CLAUDE.md`, `.mcp.json`, etc.) from the working directory, and the action's own setup steps run from there as well. + +**The caller is responsible for ensuring the working directory and prompt are trusted.** If your workflow processes untrusted input (issues, fork pull requests, external comments), use [`anthropics/claude-code-action`](https://github.com/anthropics/claude-code-action) instead — it provides actor permission checks, restores project configuration from the base ref in PR contexts, and is the supported path for those scenarios. + +See [Claude Code's security documentation](https://docs.anthropic.com/en/docs/claude-code/security) and the [GitHub Actions guidance on `pull_request_target`](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/) for background. + ## Usage Add the following to your workflow file: diff --git a/docs/security.md b/docs/security.md index a1b77f1..7a07dea 100644 --- a/docs/security.md +++ b/docs/security.md @@ -20,6 +20,39 @@ - **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 +## Using this action with `pull_request_target` or `workflow_run` + +`pull_request_target` and `workflow_run` execute with the **base repository's secrets**. If your workflow checks out the PR head (`ref: ${{ github.event.pull_request.head.sha }}` for `pull_request_target`, `ref: ${{ github.event.workflow_run.head_sha }}` for `workflow_run`) into `$GITHUB_WORKSPACE` before this action, the action and Claude run with that checkout as the working directory. + +**Do not check out an untrusted ref into the workspace root before this action.** Use one of these patterns instead: + +```yaml +# Preferred — check out the base ref (default). +- uses: actions/checkout@v6 # no `ref:` → base branch +- uses: anthropics/claude-code-action@v1 +``` + +```yaml +# If you need the PR's files locally — check out the base ref at the workspace +# root (this action expects a git repo there), then check out the head ref into +# a subdirectory and pass it via --add-dir. +- uses: actions/checkout@v6 # no `ref:` → base branch at workspace root +- uses: actions/checkout@v6 + with: + # For workflow_run use: ${{ github.event.workflow_run.head_sha }} + ref: ${{ github.event.pull_request.head.sha }} + path: pr-head +- uses: anthropics/claude-code-action@v1 + with: + claude_args: "--add-dir pr-head" +``` + +This is general guidance for these event types — see [GitHub's documentation](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/). + +### `claude-code-action` vs `claude-code-base-action` + +`claude-code-base-action` is a lower-level building block that installs and runs Claude Code with the inputs you provide. It does not perform actor permission checks or restore project configuration from the base ref. If you need those behaviors, use this action (`claude-code-action`). See the [base-action README](../base-action/README.md#trust-model) for details. + ## Pull Request Creation In its default configuration, **Claude does not create pull requests automatically** when responding to `@claude` mentions. Instead: