You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(ci): harden against template injection and credential exposure (#59)
## Summary
This patch series addresses GitHub Actions security findings from the
PSEC-923 sweep of
`chainguard-dev/setup-chainctl`. Four commits are included. Two findings
(`dangerous-triggers`, `github-env`) require human judgment and are
documented in
`manual-review.md` only.
## Patches
### 0001 — fix(ci): resolve template injection findings in action.yaml
Fixes all 36 `template-injection` findings, concentrated in the
composite `action.yaml`
at the root of this repository. The action has three `run:` blocks; all
were using
inline `${{ inputs.* }}`, `${{ runner.* }}`, and `${{ env.* }}`
expressions directly in
shell code.
**Step "Install chainctl"** (lines 94–132): Added `ENVIRONMENT: ${{
inputs.environment }}`
to the existing `env:` block to cover the `inputs.environment` inline
expansion. Replaced
`${{ runner.os }}` and `${{ runner.arch }}` with the built-in
`$RUNNER_OS` and
`$RUNNER_ARCH` env vars that the GitHub Actions runner provides
automatically — no extra
`env:` entries needed for those. Also replaced `${{
env.CURL_RETRY_ALL_ERRORS }}` with
`$CURL_RETRY_ALL_ERRORS`.
**Step "Authenticate with Chainguard (assumed identity)"** (lines
134–178): Added two
env vars to the existing `env:` block:
- `LIBRARIES_HOST: ${{ inputs.libraries-host }}`
- `APK_HOST: ${{ inputs.apk-host }}`
Replaced all remaining `${{ env.IDENTITY }}`, `${{ env.VERBOSITY }}`,
`${{ env.EXPORT_AUTH }}`, `${{ inputs.libraries-host }}`, and `${{
inputs.apk-host }}`
inline expansions with `$VAR` shell references. Also quoted
`-v="$VERBOSITY"` arguments
that were previously unquoted (`-v=${{ env.VERBOSITY }}`).
**Step "Authenticate with Chainguard (DEPRECATED invite-code)"** (lines
180–208): Added
`APK_HOST: ${{ inputs.apk-host }}` to the existing `env:` block.
Replaced all remaining
`${{ env.* }}` and `${{ inputs.apk-host }}` inline expansions. Renamed
the shell-local
`AUDIENCE` variable to `AUDIENCE_VAL` to avoid clobbering the env var
`AUDIENCE` that
is set from `inputs.audience` in the same step.
All `env:` blocks were already present before the fix; no placement
changes were needed.
All shell references use double-quoted `"$VAR"` form.
### 0002 — fix(ci): add persist-credentials: false to checkout steps
Fixes 2 `artipacked` findings:
- `.github/workflows/auth.yaml` — checkout followed only by `./` (the
composite action
under test) and `chainctl auth status`. No downstream git operations use
the credential
store. `persist-credentials: false` is correct.
- `.github/workflows/test.yaml` — checkout followed only by `./` and
`chainctl version`.
No downstream git operations. `persist-credentials: false` is correct.
### 0003 — fix(ci): add pedantic persona, zizmor.yml suppressions, and
dependabot cooldown
Three related configuration changes:
- **`.github/workflows/zizmor.yaml`**: Adds `persona: pedantic` to the
`zizmor-action`
step so that CI catches all template expansion findings, not only those
from
demonstrably attacker-controlled sources.
- **`.github/zizmor.yml`** (new file): Suppresses four pedantic-only
rules that have
no exploitable security impact:
- `concurrency-limits` — 4 findings; low security value
- `anonymous-definition` — cosmetic/style only
- `undocumented-permissions` — documentation style only
- Also sets `dependabot-cooldown: days: 3` to match the cooldown added
to `dependabot.yaml`
- **`.github/dependabot.yaml`**: Adds `cooldown: default-days: 3` to
prevent dependency
churn from same-day upstream releases that may not yet have full test
coverage.
### 0004 — fix(ci): resolve shellcheck findings in action.yaml
Fixes three shellcheck findings in the composite `action.yaml` that were
not covered by
the template-injection patch:
- **SC2046 + SC2164** (`cd $(mktemp -d)`, line 99): Quoted the subshell
and added
`|| exit` so a failed `cd` does not silently continue execution in the
wrong directory.
- **SC2086** (`>> $GITHUB_PATH`, line 129): Quoted the environment file
path in the
append redirection.
- **SC2086** (`>> $GITHUB_ENV`, lines 181 and 213): Quoted the
environment file path in
the two `HTTP_AUTH` append redirections (one in the assumed-identity
step, one in the
DEPRECATED invite-code step).
## Findings Not Patched
### `dangerous-triggers` — `auth.yaml` uses `pull_request_target` with
`id-token: write`
Documented in `manual-review.md`. This requires human judgment about the
intended
authentication testing workflow. The risk is real: any fork PR triggers
an OIDC token
request for the hardcoded Chainguard identity. Options include switching
to `pull_request`
+ GitHub environment protection, adding same-repo guards, or splitting
into push-only
auth testing.
### `github-env` — Three findings in `action.yaml`
Documented in `manual-review.md`:
1. `action.yaml:129` — `echo "$(pwd)" >> $GITHUB_PATH`: The path is a
mktemp directory,
not attacker-controlled. **Low risk; no fix needed** (the unquoted
`$GITHUB_PATH` was
addressed by SC2086 fix in 0004, but the underlying `github-env` finding
remains in
scope for zizmor).
2. `action.yaml:181` — Writing `HTTP_AUTH` with APK token to
`$GITHUB_ENV` in the
assumed-identity step. The `APK_HOST` value is caller-supplied.
Recommend validating
`APK_HOST` and masking the token. **Medium risk.**
3. `action.yaml:213` — Same pattern in the DEPRECATED invite-code step.
**Medium risk.**
Best resolved by completing migration of callers away from invite codes.
## Statistics
| Finding | Count | Action |
|---------|-------|--------|
| `template-injection` | 36 | Fixed in 0001 |
| `artipacked` | 2 | Fixed in 0002 |
| `concurrency-limits` | 4 | Suppressed in 0003 (no security impact) |
| `dependabot-cooldown` | 1 | Addressed in 0003 |
| shellcheck (SC2046/SC2164/SC2086) | 4 | Fixed in 0004 |
| `github-env` | 3 | Manual review only |
| `dangerous-triggers` | 1 | Manual review only |
## References
- Campaign: PSEC-923
- zizmor version: 1.24.1
- Sweep date: 2026-05-02
0 commit comments