diff --git a/.github/workflows/sync-translations-fa.yml b/.github/workflows/sync-translations-fa.yml index ef0c958b..b5629555 100644 --- a/.github/workflows/sync-translations-fa.yml +++ b/.github/workflows/sync-translations-fa.yml @@ -14,11 +14,22 @@ on: jobs: sync: + # The issue_comment path requires all three: a comment on a PR (not a bare + # issue), the command, and a trusted author — otherwise any account could + # fire a secrets-bearing run (Anthropic spend plus the PAT) from any comment. if: > (github.event_name == 'pull_request' && github.event.pull_request.merged == true) || - (github.event_name == 'issue_comment' && contains(github.event.comment.body, '\translate-resync')) + (github.event_name == 'issue_comment' && + github.event.issue.pull_request && + contains(github.event.comment.body, '\translate-resync') && + contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)) runs-on: ubuntu-latest + # The action authenticates with QUANTECON_SERVICES_PAT; the ambient + # GITHUB_TOKEN is unused beyond checkout, so keep it read-only. + permissions: + contents: read + steps: - uses: actions/checkout@v7 with: diff --git a/.github/workflows/sync-translations-fr.yml b/.github/workflows/sync-translations-fr.yml index 11b20591..e8fc8bdd 100644 --- a/.github/workflows/sync-translations-fr.yml +++ b/.github/workflows/sync-translations-fr.yml @@ -14,11 +14,22 @@ on: jobs: sync: + # The issue_comment path requires all three: a comment on a PR (not a bare + # issue), the command, and a trusted author — otherwise any account could + # fire a secrets-bearing run (Anthropic spend plus the PAT) from any comment. if: > (github.event_name == 'pull_request' && github.event.pull_request.merged == true) || - (github.event_name == 'issue_comment' && contains(github.event.comment.body, '\translate-resync')) + (github.event_name == 'issue_comment' && + github.event.issue.pull_request && + contains(github.event.comment.body, '\translate-resync') && + contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)) runs-on: ubuntu-latest + # The action authenticates with QUANTECON_SERVICES_PAT; the ambient + # GITHUB_TOKEN is unused beyond checkout, so keep it read-only. + permissions: + contents: read + steps: - uses: actions/checkout@v7 with: diff --git a/.github/workflows/sync-translations-zh-cn.yml b/.github/workflows/sync-translations-zh-cn.yml index a92810cc..9296d879 100644 --- a/.github/workflows/sync-translations-zh-cn.yml +++ b/.github/workflows/sync-translations-zh-cn.yml @@ -14,11 +14,22 @@ on: jobs: sync: + # The issue_comment path requires all three: a comment on a PR (not a bare + # issue), the command, and a trusted author — otherwise any account could + # fire a secrets-bearing run (Anthropic spend plus the PAT) from any comment. if: > (github.event_name == 'pull_request' && github.event.pull_request.merged == true) || - (github.event_name == 'issue_comment' && contains(github.event.comment.body, '\translate-resync')) + (github.event_name == 'issue_comment' && + github.event.issue.pull_request && + contains(github.event.comment.body, '\translate-resync') && + contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)) runs-on: ubuntu-latest + # The action authenticates with QUANTECON_SERVICES_PAT; the ambient + # GITHUB_TOKEN is unused beyond checkout, so keep it read-only. + permissions: + contents: read + steps: - uses: actions/checkout@v7 with: