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.
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)