Skip to content

gh aw compile expands safe-output token secrets into runtime config file (${RUNNER_TEMP}/gh-aw/safeoutputs/config.json) #36324

@pholleran

Description

@pholleran

Summary

When compiling a workflow that configures a safe output with github-token from secrets, the generated .lock.yml writes the token value into ${RUNNER_TEMP}/gh-aw/safeoutputs/config.json at runtime via an unquoted heredoc, causing secret materialization on disk.

Why this is a bug

This increases secret exposure surface unnecessarily (debug logs, accidental artifact collection, or other file disclosure paths), even though the safe output processing step already receives a token directly at execution time.

Reproduction

Given workflow frontmatter like:

safe-outputs:
  update-project:
    project: https://github.com/orgs/github/projects/24263
    github-token: "${{ secrets.WRITE_PROJECT_PAT }}"

gh aw compile generates lockfile logic equivalent to:

cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << EOCONFIG
{"update_project":{"github-token":"${WRITE_PROJECT_PAT}", ...}}
EOCONFIG

with WRITE_PROJECT_PAT populated from ${{ secrets.WRITE_PROJECT_PAT }}.

Actual behavior

Secret token is expanded and written into config.json on disk in runner temp storage.

Expected behavior

gh-aw should avoid writing secret token values to disk in generated config files.
Prefer passing token only through environment/step inputs at execution time, or referencing secret placeholders that are resolved in-memory by the handler.

Suggested fix

  1. Avoid unquoted heredoc expansion for secret-bearing fields.
  2. Omit github-token from on-disk config when an equivalent runtime env/input token is already provided.
  3. Ensure no safe-output secret values are persisted to temp files by default.

Metadata

Metadata

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions