Skip to content

Enable Factory Droid @droid tag responses#189

Open
HeyGarrison wants to merge 3 commits into
masterfrom
add-factory-workflows-1784302505
Open

Enable Factory Droid @droid tag responses#189
HeyGarrison wants to merge 3 commits into
masterfrom
add-factory-workflows-1784302505

Conversation

@HeyGarrison

Copy link
Copy Markdown
Collaborator

This PR adds the Factory Droid @droid tag response workflow. When someone mentions @droid in an issue or PR comment, Droid will respond automatically.

The workflow uses the Factory-AI/droid-action@main GitHub Action and authenticates with the FACTORY_API_KEY org secret (already configured for the computesdk org).

Learn more at https://docs.factory.ai
Generate an API key at https://app.factory.ai/settings/api-keys

@open-cla

open-cla Bot commented Jul 17, 2026

Copy link
Copy Markdown

Contributor License Agreement

All contributors are covered by a CLA.

@factory-droid

factory-droid Bot commented Jul 17, 2026

Copy link
Copy Markdown

Droid finished @HeyGarrison's task —— View job


The workflow change is small and aligns with enabling @droid responses, but it would benefit from hardening: restrict triggering to trusted sources to avoid noisy failing runs and potential re-triggers from untrusted issue/PR bodies, and pin the third-party action to a commit SHA since it runs with secrets and write permissions.

Comment thread .github/workflows/droid.yml Outdated
Comment on lines +17 to +22
if: |
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@droid')) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@droid')) ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@droid')) ||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@droid') || contains(github.event.issue.title, '@droid'))) ||
(github.event_name == 'pull_request' && (contains(github.event.pull_request.body, '@droid') || contains(github.event.pull_request.title, '@droid')))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[P1] Gate @droid runs to avoid noisy failures and wasted CI

As written, any issue/PR comment (or issue/PR body) containing @droid will start the workflow even when the mention comes from an untrusted source, which can lead to avoidable failing runs (the action later rejects non-write actors) and, for issues/pull_request events, can allow an untrusted @droid mention in the entity body to be re-triggered later by a maintainer action like assignment; also, coercing *.body/*.title to '' avoids potential expression errors when those fields are null.

Suggested change
if: |
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@droid')) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@droid')) ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@droid')) ||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@droid') || contains(github.event.issue.title, '@droid'))) ||
(github.event_name == 'pull_request' && (contains(github.event.pull_request.body, '@droid') || contains(github.event.pull_request.title, '@droid')))
if: |
(github.event_name == 'issue_comment' && (github.event.comment.author_association == 'OWNER' || github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'COLLABORATOR') && contains(github.event.comment.body || '', '@droid')) ||
(github.event_name == 'pull_request_review_comment' && (github.event.comment.author_association == 'OWNER' || github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'COLLABORATOR') && contains(github.event.comment.body || '', '@droid')) ||
(github.event_name == 'pull_request_review' && (github.event.review.author_association == 'OWNER' || github.event.review.author_association == 'MEMBER' || github.event.review.author_association == 'COLLABORATOR') && contains(github.event.review.body || '', '@droid')) ||
(github.event_name == 'issues' && (github.event.issue.author_association == 'OWNER' || github.event.issue.author_association == 'MEMBER' || github.event.issue.author_association == 'COLLABORATOR') && (contains(github.event.issue.body || '', '@droid') || contains(github.event.issue.title || '', '@droid'))) ||
(github.event_name == 'pull_request' && (github.event.pull_request.author_association == 'OWNER' || github.event.pull_request.author_association == 'MEMBER' || github.event.pull_request.author_association == 'COLLABORATOR') && (contains(github.event.pull_request.body || '', '@droid') || contains(github.event.pull_request.title || '', '@droid')))

Comment thread .github/workflows/droid.yml Outdated
with:
fetch-depth: 1
- name: Run Droid Exec
uses: Factory-AI/droid-action@main

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[P1] Pin Factory-AI/droid-action to a commit SHA

Using Factory-AI/droid-action@main means each run executes mutable code from that branch; since this workflow provides a long-lived API key secret and write permissions for issues/PRs, pinning to a specific commit SHA (or a release tag that is itself pinned) reduces supply-chain risk and makes executions reproducible.

Suggested change
uses: Factory-AI/droid-action@main
uses: Factory-AI/droid-action@7c7bfea2aa3bb7ea87579402cc1d89dbcf6b13b3

@superagent-security superagent-security Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Superagent found 3 security concern(s).

Comment thread .github/workflows/droid.yml Outdated
with:
fetch-depth: 1
- name: Run Droid Exec
uses: Factory-AI/droid-action@main

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1: Workflow uses unpinned third-party action with mutable main reference

Unpinned third-party action Factory-AI/droid-action@main receives a long-lived API key and write permissions.

Pin the action to a specific commit SHA to prevent supply-chain attacks.

AI prompt
Check if this security scanner issue is valid. If so, understand the root cause and fix it. If appropriate, update or add tests. Keep the change focused and preserve intended behavior.

<file name=".github/workflows/droid.yml">
<violation number="1" location=".github/workflows/droid.yml:30">
<priority>P1</priority>
<title>Workflow uses unpinned third-party action with mutable `main` reference</title>
<evidence>The step at line 30 references `Factory-AI/droid-action@main`. A branch reference can point to different commits over time without review by this repository's maintainers. Because this workflow passes a sensitive `FACTORY_API_KEY` secret and grants write permissions (`issues: write`, `pull-requests: write`), using a mutable reference exposes the repository to supply-chain compromise if the upstream repository is compromised.</evidence>
<recommendation>Pin `Factory-AI/droid-action` to a specific commit SHA or a verified, immutable release tag.</recommendation>
</violation>
</file>


jobs:
droid:
if: |

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1: Workflow triggers on untrusted issue comments without author validation

Untrusted users can trigger third-party action runs by posting @droid in public issue comments.

Add author_association checks to the if condition to only run for trusted collaborators.

AI prompt
Check if this security scanner issue is valid. If so, understand the root cause and fix it. If appropriate, update or add tests. Keep the change focused and preserve intended behavior.

<file name=".github/workflows/droid.yml">
<violation number="1" location=".github/workflows/droid.yml:13">
<priority>P1</priority>
<title>Workflow triggers on untrusted issue comments without author validation</title>
<evidence>The workflow fires on `issue_comment` events without checking the comment author's trust level. Any GitHub user can create an issue comment on a public repository containing `@droid`, causing this workflow to run a third-party action with access to repository secrets (`FACTORY_API_KEY`) and write permissions (`issues: write`, `pull-requests: write`). The `if` block only checks for the `@droid` string but does not verify `github.event.comment.author_association`.</evidence>
<recommendation>Restrict the `issue_comment` trigger to trusted authors by checking `github.event.comment.author_association` (e.g., OWNER, MEMBER, COLLABORATOR) before running the third-party action.</recommendation>
</violation>
</file>

Comment thread .github/workflows/droid.yml Outdated
contents: read
pull-requests: write
issues: write
id-token: write

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: Overly broad workflow permissions include id-token: write and actions: read

Job grants id-token: write and actions: read, neither of which is needed for a comment-responding bot.

Remove unnecessary permissions and use least-privilege access.

AI prompt
Check if this security scanner issue is valid. If so, understand the root cause and fix it. If appropriate, update or add tests. Keep the change focused and preserve intended behavior.

<file name=".github/workflows/droid.yml">
<violation number="1" location=".github/workflows/droid.yml:22">
<priority>P2</priority>
<title>Overly broad workflow permissions include `id-token: write` and `actions: read`</title>
<evidence>The workflow grants `id-token: write` (line 22) and `actions: read` (line 23). The `id-token: write` permission allows generation of OIDC ID tokens that can be exchanged for cloud credentials. The `actions: read` permission enables reading workflow runs and artifacts. Neither permission is required for a commenting bot that receives an explicit API key. These permissions expand the blast radius if the third-party action is compromised.</evidence>
<recommendation>Remove `id-token: write` and `actions: read` from the job permissions, or document why they are necessary. Apply least-privilege permissions.</recommendation>
</violation>
</file>

@superagent-security superagent-security Bot added the pr:flagged PR flagged for review by security analysis. label Jul 18, 2026

@superagent-security superagent-security Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Superagent found 1 new security concern(s).

@@ -0,0 +1,38 @@
name: Droid Tag

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: Workflow lacks top-level permissions block to restrict default GITHUB_TOKEN scope

No top-level permissions block means default token permissions depend on repo settings.

Add permissions: {} at the workflow level for defense-in-depth.

AI prompt
Check if this security scanner issue is valid. If so, understand the root cause and fix it. If appropriate, update or add tests. Keep the change focused and preserve intended behavior.

<file name=".github/workflows/droid.yml">
<violation number="1" location=".github/workflows/droid.yml:1">
<priority>P2</priority>
<title>Workflow lacks top-level permissions block to restrict default GITHUB_TOKEN scope</title>
<evidence>The workflow does not declare a top-level permissions block, so any additional jobs added later would inherit the repository's default GITHUB_TOKEN permissions, which may be broader than intended. The single job in this workflow does have explicit job-level permissions, but adding permissions: {} at the workflow level is a defense-in-depth measure recommended by GitHub and the OpenSSF.</evidence>
<recommendation>Add permissions: {} at the top level of the workflow (before or after the on: block) so that the default token scope is empty and every job must explicitly declare its own permissions.</recommendation>
</violation>
</file>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:flagged PR flagged for review by security analysis.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant