feat: forward SSH_SIGNING_KEY secret to code agent sandbox - #5349
feat: forward SSH_SIGNING_KEY secret to code agent sandbox#5349lahavyuv86 wants to merge 1 commit into
Conversation
E2E tests did not runE2E tests run automatically for org/repo members and collaborators on pull requests. For other contributors, a maintainer must add the See E2E testing guide for details. |
PR Summary by QodoForward SSH_SIGNING_KEY secret into code agent sandbox
AI Description
Diagram
High-Level Assessment
Files changed (1)
|
84a230e to
5aa38a7
Compare
Site previewPreview: https://f0b32494-site.fullsend-ai.workers.dev Commit: |
Enables repos to opt into SSH commit signing by setting an
SSH_SIGNING_KEY repo secret. The setup-agent-env script strips
the CODE_ prefix and exports it for fullsend run to expand
into env.sandbox.
Signed-off-by: Yuval Lahav <ylahav@redhat.com>
5aa38a7 to
a5ede36
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Code Review by Qodo
1. Incomplete secret forwarding
|
| AGENT_PREFIX: CODE_ | ||
| CODE_TARGET_REPO_DIR: target-repo | ||
| CODE_ANTHROPIC_VERTEX_PROJECT_ID: ${{ secrets.FULLSEND_GCP_PROJECT_ID }} | ||
| CODE_SSH_SIGNING_KEY: ${{ secrets.SSH_SIGNING_KEY }} |
There was a problem hiding this comment.
1. ssh_signing_key missing in scaffold dispatch 📘 Rule violation ⚙ Maintainability
.github/workflows/reusable-dispatch.yml now declares and forwards SSH_SIGNING_KEY (as CODE_SSH_SIGNING_KEY) but the scaffolded dispatch workflow does not declare/thread the same secret, creating workflow divergence. This violates the requirement to keep dispatch secret-threading logic in sync unless the divergence is explicitly documented inline.
Agent Prompt
## Issue description
The reusable dispatch workflow added support for `SSH_SIGNING_KEY`, but `internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml` was not updated to match (and there is no inline comment documenting an intentional divergence).
## Issue Context
Compliance requires `.github/workflows/reusable-dispatch.yml` and `internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml` to keep jq payload/routing and input/secret threading logic in sync, or explicitly document any intentional differences inline.
## Fix Focus Areas
- .github/workflows/reusable-dispatch.yml[62-79]
- .github/workflows/reusable-dispatch.yml[665-674]
- internal/scaffold/fullsend-repo/.github/workflows/dispatch.yml[9-17]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| secret). Optional — unset leaves export disabled unless the | ||
| endpoint variable alone suffices. | ||
| required: false | ||
| SSH_SIGNING_KEY: |
There was a problem hiding this comment.
2. Incomplete secret forwarding 🐞 Bug ≡ Correctness
SSH_SIGNING_KEY is added as a workflow_call secret and only forwarded into the direct code job as CODE_SSH_SIGNING_KEY, but other agent entrypoints (the harness-run matrix path and reusable-code.yml) never accept/propagate this secret. Repos invoking the code agent via those paths cannot enable SSH commit signing even if the repo secret exists.
Agent Prompt
## Issue description
`SSH_SIGNING_KEY` is exposed on `reusable-dispatch.yml`'s `workflow_call` interface, but it is only mapped into the direct `code` job environment (`CODE_SSH_SIGNING_KEY`). Other execution paths that run agents (notably the harness-run matrix execution, and the standalone `reusable-code.yml` workflow) do not declare or forward this secret, so SSH signing cannot work consistently across the system.
## Issue Context
`setup-agent-env.sh` only forwards env vars that are explicitly present in the workflow step env; it does not magically access `secrets.*`. So each workflow/entrypoint that can run the code agent must (1) declare the secret on its `workflow_call` interface and (2) map it into the agent-prefixed env vars before calling `setup-agent-env.sh`.
## Fix Focus Areas
- .github/workflows/reusable-dispatch.yml[1517-1530]
- .github/workflows/reusable-code.yml[44-49]
- .github/workflows/reusable-dispatch.yml[62-79]
- .github/workflows/reusable-dispatch.yml[665-674]
### Suggested implementation sketch
1) **harness-run matrix path:** add `SSH_SIGNING_KEY: ${{ secrets.SSH_SIGNING_KEY }}` to the step env and export `${ROLE_UPPER}_SSH_SIGNING_KEY` (optionally only when non-empty) before running `setup-agent-env.sh`.
2) **reusable-code.yml:**
- Declare `SSH_SIGNING_KEY` under `on.workflow_call.secrets`.
- Map it as `CODE_SSH_SIGNING_KEY: ${{ secrets.SSH_SIGNING_KEY }}` in its "Setup agent environment" step (same pattern as in `reusable-dispatch.yml`).
3) If fix/review agents are also expected to produce signed commits, repeat the pattern in their reusable workflows as well (declare secret + map to `FIX_SSH_SIGNING_KEY`, etc.).
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
|
/fs-review |
|
🤖 Finished Review · ✅ Success · Started 1:38 PM UTC · Completed 1:52 PM UTC |
ReviewFindingsMedium
Low
Labels: PR modifies dispatch workflow to forward SSH signing secret to the code agent sandbox |
| AGENT_PREFIX: CODE_ | ||
| CODE_TARGET_REPO_DIR: target-repo | ||
| CODE_ANTHROPIC_VERTEX_PROJECT_ID: ${{ secrets.FULLSEND_GCP_PROJECT_ID }} | ||
| CODE_SSH_SIGNING_KEY: ${{ secrets.SSH_SIGNING_KEY }} |
There was a problem hiding this comment.
[medium] consumer completeness
The diff forwards SSH_SIGNING_KEY into the code agent sandbox via CODE_SSH_SIGNING_KEY, and setup-agent-env.sh will correctly strip the CODE_ prefix. However, there is no consumer of this environment variable anywhere in the codebase. The sandbox image (images/code/Containerfile) is configured for gitsign (x509 signing), not SSH-based signing. The PR description references a gpg.ssh.program wrapper that does not exist yet. Without a consumer, this secret is forwarded into the sandbox environment but never used.
Suggested fix: Either land the gpg.ssh.program wrapper and git config changes that consume SSH_SIGNING_KEY in the same PR or a predecessor, or defer this plumbing PR until the consumer exists.
| CODE_ANTHROPIC_VERTEX_PROJECT_ID: ${{ secrets.FULLSEND_GCP_PROJECT_ID }} | ||
| CODE_SSH_SIGNING_KEY: ${{ secrets.SSH_SIGNING_KEY }} | ||
| CODE_CLOUD_ML_REGION: ${{ inputs.gcp_region }} | ||
| CODE_ISSUE_NUMBER: ${{ fromJSON(needs.route.outputs.event_payload).issue.number }} |
There was a problem hiding this comment.
[medium] secret-exposure
The SSH private key secret is passed as CODE_SSH_SIGNING_KEY and written to GITHUB_ENV by setup-agent-env.sh. GitHub Actions automatically masks values referenced via ${{ secrets.* }}, but once the secret is re-exported to GITHUB_ENV through the shell script (via printenv and heredoc), the re-exported value may not be covered by GitHub's masking. If any subsequent step logs the SSH_SIGNING_KEY env var, the private key material could appear in workflow logs.
Suggested fix: Add an explicit echo "::add-mask::${CODE_SSH_SIGNING_KEY}" before writing the secret to GITHUB_ENV, or add masking logic to setup-agent-env.sh for all secret-sourced values.
| secret). Optional — unset leaves export disabled unless the | ||
| endpoint variable alone suffices. | ||
| required: false | ||
| SSH_SIGNING_KEY: |
There was a problem hiding this comment.
[low] scope-misalignment
The linked issue #1685 investigated gitsign (keyless Sigstore signing), while this PR implements SSH key-based signing plumbing. These are different signing mechanisms. The PR correctly uses 'related to' rather than 'fixes', and this is opt-in plumbing that does not commit to a signing architecture. A brief note in the PR description explaining why SSH signing was chosen alongside or instead of gitsign would clarify the design direction.
|
We are coming with a new approach. |
|
🤖 Finished Retro · ✅ Success · Started 9:50 AM UTC · Completed 10:15 AM UTC |
Retro: PR #5349 — Forward SSH_SIGNING_KEY secret to code agent sandboxOutcome: Closed without merge after 2 days. Human maintainer closed with "We are coming with a new approach." Review Quality: HighThe fullsend review agent performed well on this external contributor PR. All 5 findings were valid with no false positives:
Both Qodo and fullsend-review converged on scaffold sync and incomplete forwarding, with fullsend finding additional security and design concerns. The CHANGES_REQUESTED verdict was appropriate. Review completed in ~16 minutes. Notable: Design-Level Review CapabilityThe Evidence for Existing Issues
No New ProposalsAll improvement opportunities identified are already covered by existing open issues. The review agent performed well — findings were accurate, no false positives, and the review likely contributed to the team's decision to pursue a different signing approach. |
Summary
Enables repos to opt into SSH commit signing by setting an SSH_SIGNING_KEY repo secret.
The setup-agent-env script strips the CODE_ prefix and exports it for fullsend run to expand into env.sandbox.
Related Issue
related to: #1685
Changes
SSH_SIGNING_KEYas an optional secret input inon.workflow_call.secretsCODE_SSH_SIGNING_KEYto the code agent's "Setup agent environment" step, following the same pattern asCODE_ANTHROPIC_VERTEX_PROJECT_IDTesting
make lintpasses (stage changes first, then run)Checklist
!for breaking changes)