Skip to content

ci(#5221): redact behaviour debug artifacts before upload - #6167

Merged
ifireball merged 7 commits into
fullsend-ai:mainfrom
ifireball:fix/5221-redact-behaviour-artifacts
Aug 13, 2026
Merged

ci(#5221): redact behaviour debug artifacts before upload#6167
ifireball merged 7 commits into
fullsend-ai:mainfrom
ifireball:fix/5221-redact-behaviour-artifacts

Conversation

@ifireball

Copy link
Copy Markdown
Member

Summary

  • Add a base-branch redaction script that runs before behaviour debug artifacts are uploaded on failure, so PR-head code cannot disable or weaken secret scrubbing (e2e: behaviour debug artifacts can exfiltrate secrets without redaction #5221).
  • Redact plain text (logs, JSON, JSONL), nested archives (zip/tar.gz/gzip), and literal behaviour-job secrets; tee make behaviour-test output into behaviour-test.log for the same pass.
  • Always stub encrypted, binary, and media files — behaviour debug artifacts are text-only today, and unscannable formats are an exfiltration channel (e.g. base64 in a fake .gif).

Test plan

  • bash .github/scripts/redact-behaviour-artifacts-test.sh
  • CI script-test / lint workflow on PR
  • Maintainer review of .github/workflows/e2e.yml redaction step wiring

Fixes #5221

Made with Cursor

ifireball and others added 2 commits August 13, 2026 11:09
Authorized PR-head code can populate behaviour-artifacts with downloaded
workflow output and attacker-controlled files. Scan and redact text, nested
archives, and job logs before upload; stub encrypted blobs and binary files
that embed known secrets. Run redaction from a base-branch script PRs cannot
override.

Signed-off-by: Barak Korren <bkorren@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Behaviour debug artifacts are text and JSON only; keeping unscannable
binary/media files allows exfiltration via disguised formats (e.g. base64
in a fake .gif). Stub all binary, media, and gzip-with-NUL payloads.

Signed-off-by: Barak Korren <bkorren@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@ifireball
ifireball requested a review from a team as a code owner August 13, 2026 08:39
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 13, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 8:40 AM UTC · Completed 8:59 AM UTC

Commit: fd7ebc3 · View workflow run →

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Redact behaviour debug artifacts with base-branch script before upload

🐞 Bug fix 🧪 Tests 📝 Documentation ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Run a base-branch redaction pass over behaviour debug artifacts before uploading on failure.
• Redact secrets in text files and nested archives; stub encrypted, binary, and media artifacts.
• Tee behaviour test output into an artifact log so it is sanitized and uploaded safely.
Diagram

graph TD
  A["GitHub Actions: e2e job"] --> B["Run behaviour tests"] --> C[("behaviour-artifacts dir")]
  B --> D["tee -> behaviour-test.log"] --> C
  A --> E["Checkout base redaction script"] --> F["Redact artifacts"] --> C --> G["Upload artifact"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Only upload allowlisted text extensions (drop everything else)
  • ➕ Simpler implementation than recursive archive inspection
  • ➕ Smaller attack surface; avoids any decompression risks
  • ➖ Less debuggability if future artefacts legitimately include non-text
  • ➖ Still needs careful handling of archives (zip/gz) unless they are fully banned
2. Generate failure bundle from workflow logs / known outputs only
  • ➕ Avoids trusting any files written by PR-head code into artifact dirs
  • ➕ Reduces need for complex file-type detection and recursive extraction
  • ➖ May miss important debug context currently emitted as files
  • ➖ Requires reworking how behaviour tests persist artifacts (more intrusive change)
3. Remove long-lived secrets from behaviour job (OIDC/short-lived creds)
  • ➕ Best defense-in-depth: even if exfiltration occurs, blast radius is reduced
  • ➕ Less reliance on redaction correctness
  • ➖ May not be feasible for all integrations (PATs, external providers)
  • ➖ Larger change spanning auth and test infrastructure

Recommendation: Keep the PR’s approach: checking out and executing a base-branch redaction script is the most practical and robust control against PR-head tampering under pull_request_target. The added hard-stubbing of encrypted/binary/media files is a good security tradeoff given current artifacts are intended to be text-only; consider optionally layering an allowlist later if debuggability needs change.

Files changed (5) +554 / -3

Bug fix (1) +369 / -0
redact-behaviour-artifacts.shAdd base-branch artifact redaction script with archive support +369/-0

Add base-branch artifact redaction script with archive support

• Adds a defensive redaction script that sanitizes behaviour debug artifacts in-place. Redacts private key blocks and token patterns, removes literal secrets sourced from workflow env, recursively inspects zip/tar.gz/gzip within size limits, and replaces encrypted/binary/media files with a warning stub.

.github/scripts/redact-behaviour-artifacts.sh

Tests (2) +139 / -1
redact-behaviour-artifacts-test.shAdd shell tests for behaviour artifact redaction +137/-0

Add shell tests for behaviour artifact redaction

• Introduces a standalone bash test suite that exercises PEM/token redaction, literal secret removal via env vars, archive (gzip/zip) traversal, and stubbing of encrypted/media-like payloads. Validates that sanitized output removes secrets while preserving non-secret content.

.github/scripts/redact-behaviour-artifacts-test.sh

MakefileRun redaction script tests in script-test target +2/-1

Run redaction script tests in script-test target

• Extends 'script-test' to execute the new redaction test script and updates the help text to include artifact redaction coverage.

Makefile

Documentation (1) +13 / -0
ci-workflows.mdDocument behaviour artifact redaction threat model and workflow +13/-0

Document behaviour artifact redaction threat model and workflow

• Documents why behaviour artifacts need sanitization under 'pull_request_target', how the workflow ensures the base-branch script is used, and what file types are redacted versus stubbed.

docs/contributing/ci-workflows.md

Other (1) +33 / -2
e2e.ymlWire redaction into behaviour failure artifact upload flow +33/-2

Wire redaction into behaviour failure artifact upload flow

• Captures behaviour test output into the artifact directory via 'tee' and, on failure, checks out the redaction script from the base branch into a separate path. Runs the redaction step with secrets provided via env before uploading debug artifacts, preventing PR-head code from bypassing sanitization.

.github/workflows/e2e.yml

@github-actions

github-actions Bot commented Aug 13, 2026

Copy link
Copy Markdown

Site preview

Preview: https://583ddf35-site.fullsend-ai.workers.dev

Commit: c4d8de3a62e9599d40a882f14a4418f8c019016e

@qodo-code-review

qodo-code-review Bot commented Aug 13, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Sed flag breaks redaction ✓ Resolved 🐞 Bug ≡ Correctness
Description
In _redact_patterns, sed uses substitution flags gi, which is invalid under GNU sed
(case-insensitive flag is I), causing sed to exit non-zero; under set -euo pipefail this
aborts redaction. In the workflow, that failed redaction step prevents the subsequent
upload-artifact step from running, so behaviour artifacts will not be uploaded.
Code

.github/scripts/redact-behaviour-artifacts.sh[R89-91]

+    -e 's/x-access-token:[^@[:space:]]+/x-access-token:[REDACTED]/g' \
+    -e 's/(Bearer|token)[[:space:]]+[A-Za-z0-9._-]+/\1 [REDACTED]/gi' \
+    -e 's/ya29\.[A-Za-z0-9._-]+/[REDACTED]/g'
Relevance

●●● Strong

Deterministic script bug under set -e; team commonly fixes nonzero-exit pitfalls in shell pipelines.

PR-#390
PR-#3610

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The redaction script runs with set -euo pipefail and calls sed with an invalid gi flag, which
will cause the script to exit non-zero. The workflow runs this script in a dedicated step before the
artifact upload step, so a failure prevents uploading.

.github/scripts/redact-behaviour-artifacts.sh[14-15]
.github/scripts/redact-behaviour-artifacts.sh[85-92]
.github/workflows/e2e.yml[282-317]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`_redact_patterns()` uses `sed` substitution flags `gi`. GNU `sed` supports case-insensitive matching via the **uppercase** `I` flag, so `gi` causes `sed` to error and exit non-zero. Because the script runs with `set -euo pipefail`, this stops the redaction script and blocks subsequent workflow steps (including artifact upload).

### Issue Context
This script is executed in `.github/workflows/e2e.yml` on failure before uploading `${{ runner.temp }}/behaviour-artifacts/`. If the redaction step fails, later steps won’t run.

### Fix Focus Areas
- .github/scripts/redact-behaviour-artifacts.sh[85-92]
- .github/workflows/e2e.yml[282-317]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Unvalidated archive extraction ✓ Resolved 🐞 Bug ⛨ Security
Description
The redaction script extracts attacker-controlled .zip and .tar.gz artifacts using unzip/tar
without any explicit validation of member paths or link types. Depending on archive contents/tool
behavior (e.g., .. paths, absolute paths, symlinks/hardlinks), this can lead to unsafe writes or
link creation outside the intended extraction tree during pull_request_target runs.
Code

.github/scripts/redact-behaviour-artifacts.sh[R261-263]

+  if ! tar -xzf "${file}" -C "${workdir}"; then
+    rm -rf "${tmpdir}"
+    _stub_opaque_file "${file}" "could not be extracted as tar.gz"
Relevance

●● Moderate

Team accepts symlink/path containment hardening, but archive member validation for tar/zip is more
involved; unclear if required.

PR-#1177

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
unzip and tar are invoked directly on artifact files into a temp directory, with no
pre-extraction inspection of member names/paths or file types (symlinks/hardlinks), which is the
missing defense in the current implementation.

.github/scripts/redact-behaviour-artifacts.sh[227-251]
.github/scripts/redact-behaviour-artifacts.sh[253-277]
.github/workflows/e2e.yml[292-317]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
Archive redaction currently performs extraction of untrusted archives without pre-validating entry paths or rejecting link/special entries. This can allow unsafe archive structures (path traversal, symlinks/hardlinks) to affect files outside the extraction directory, depending on tool behavior.

### Issue Context
The artifact directory is populated by PR-head code under `pull_request_target`, so archives in that directory must be treated as attacker-controlled input.

### Fix Focus Areas
- .github/scripts/redact-behaviour-artifacts.sh[227-277]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Hardcoded ghp_... test token ✓ Resolved 📘 Rule violation ⛨ Security
Description
The new artifact-redaction test script embeds secret-like literals (e.g., ghp_... PAT format and
PEM private key markers) directly in the repository, which violates the prohibition on hardcoded
secrets/token-like strings. Even if intended as synthetic test data, these patterns can trigger
secret scanning and create audit/compliance risk.
Code

.github/scripts/redact-behaviour-artifacts-test.sh[R68-72]

+cat >"${TMPDIR}/artifact.log" <<'EOF'
+auth failed with ghp_**********************************90
+EOF
+run_redaction
+run_test "redacts-ghp-token" "ghp_**********************************90"
Relevance

●●● Strong

Repo has precedent using ghp_/ghs_ token-shaped strings in tests; likely adjust to non-scannable
placeholder.

PR-#1178
PR-#736

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 1062040 disallows hardcoded secrets and token-like strings in changed files. The
added test script includes a GitHub PAT-shaped ghp_... token literal and private-key PEM markers,
which are explicitly listed as prohibited patterns in the rule.

Rule 1062040: Disallow hardcoded secrets and sensitive environment-specific identifiers in source code
.github/scripts/redact-behaviour-artifacts-test.sh[68-72]
.github/scripts/redact-behaviour-artifacts-test.sh[52-60]
.github/scripts/redact-behaviour-artifacts-test.sh[91-99]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`.github/scripts/redact-behaviour-artifacts-test.sh` contains hardcoded secret-like strings (e.g., `ghp_...`-prefixed token, PEM private key markers). The compliance rule disallows embedding token-like strings/crypto material in source, even in tests.

## Issue Context
These values are used only to exercise the redaction logic; they do not need to exist as contiguous, scanner-detectable literals in the repo.

## Fix Focus Areas
- .github/scripts/redact-behaviour-artifacts-test.sh[52-60]
- .github/scripts/redact-behaviour-artifacts-test.sh[67-72]
- .github/scripts/redact-behaviour-artifacts-test.sh[91-99]

### Suggested approach
- Construct synthetic token strings at runtime from non-secret-looking pieces (e.g., concatenate `"gh""p_"` + generated filler) so no contiguous `ghp_[A-Za-z0-9_]{...}` literal exists in the file.
- Likewise, build PEM marker lines from split fragments (or generate them via `printf` with separated substrings) so `-----BEGIN ... PRIVATE KEY-----` does not appear verbatim.
- For the base64 sample, generate it from plaintext during the test (e.g., `printf 'fake-secret-payload' | base64`) rather than embedding the encoded blob.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Archive limits post-extract ✓ Resolved 🐞 Bug ☼ Reliability
Description
ZIP and tar.gz handlers extract archives before checking ARCHIVE_TOTAL_LIMIT, so oversized
archives can consume disk/CPU before being stubbed. Additionally, ZIP/tar.gz redaction never
enforces ARCHIVE_PER_FILE_LIMIT, so a single large member can still cause excessive resource use
even when the total limit is not exceeded.
Code

.github/scripts/redact-behaviour-artifacts.sh[R235-238]

+  if ! unzip -q "${file}" -d "${workdir}"; then
+    rm -rf "${tmpdir}"
+    _stub_opaque_file "${file}" "could not be extracted as zip"
+    return 0
Relevance

●● Moderate

Resource-limit hardening is plausible but requires redesign (pre-extract checks/per-file
enforcement); no close script precedent.

PR-#337
PR-#1954

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Both ZIP and tar.gz paths call unzip/tar -xzf first, and only then call
_archive_tree_within_limits to check ARCHIVE_TOTAL_LIMIT, meaning the extraction can already
have expanded beyond safe bounds. Only the gzip path checks ARCHIVE_PER_FILE_LIMIT explicitly, so
ZIP/tar.gz have no per-file enforcement at all.

.github/scripts/redact-behaviour-artifacts.sh[18-21]
.github/scripts/redact-behaviour-artifacts.sh[235-245]
.github/scripts/redact-behaviour-artifacts.sh[261-271]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
Size limits are checked only after extraction for ZIP/tar.gz via `du -sb`, which does not prevent extraction work/resource use for oversized or bomb-like archives. The per-file limit is also only applied to the gzip path, not ZIP/tar.gz.

### Issue Context
The script advertises limits synced with behaviour artifact download limits, but current enforcement occurs too late to prevent the extraction itself.

### Fix Focus Areas
- .github/scripts/redact-behaviour-artifacts.sh[18-21]
- .github/scripts/redact-behaviour-artifacts.sh[227-251]
- .github/scripts/redact-behaviour-artifacts.sh[253-277]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context
✅ Compliance rules (platform): 54 rules

Grey Divider

Tip of the day
💡 Did you know, you can type 'qodo, fix this' on a finding and the fix lands right on your PR

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread .github/scripts/redact-behaviour-artifacts-test.sh Outdated
Comment thread .github/scripts/redact-behaviour-artifacts.sh
Comment thread .github/scripts/redact-behaviour-artifacts.sh Outdated
Comment thread .github/scripts/redact-behaviour-artifacts.sh Outdated
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 13, 2026

Copy link
Copy Markdown

Review

Findings

Medium

  • [protected-path] .github/scripts/redact-behaviour-artifacts-test.sh, .github/scripts/redact-behaviour-artifacts.sh, .github/workflows/e2e.yml — This PR modifies files under protected paths (.github/). The PR links to issue e2e: behaviour debug artifacts can exfiltrate secrets without redaction #5221 and explains the rationale for modifying governance/infrastructure files. Human approval is always required for protected-path changes, regardless of context.

Low

  • [edge-case] .github/scripts/redact-behaviour-artifacts.sh:125_redact_text_content and _redact_text_file strip trailing newlines from files during redaction. The $(_read_text_file ...) command substitution in bash drops trailing newlines, and printf '%s' does not restore them. This is cosmetic and does not affect security.

  • [secrets-handling] .github/scripts/redact-behaviour-artifacts.sh:373 — The _redact_patterns regex for Bearer/token auth headers ((Bearer|token)[[:space:]]+[A-Za-z0-9._-]+) would not match tokens containing characters outside [A-Za-z0-9._-], such as tokens with / or + (common in base64-encoded values). Risk is low because the ya29 pattern is a separate catch-all for GCP tokens, and literal secret redaction handles known job secrets independently of pattern matching.
    Remediation: Widen the Bearer/token character class to include base64 characters: [A-Za-z0-9._+/=-]+ or use [^[:space:]]+ to match until the next whitespace.

Previous run

Review

Findings

Medium

  • [protected-path] .github/scripts/redact-behaviour-artifacts-test.sh, .github/scripts/redact-behaviour-artifacts.sh, .github/workflows/e2e.yml — This PR modifies files under protected paths (.github/). The PR links to issue e2e: behaviour debug artifacts can exfiltrate secrets without redaction #5221 and explains the rationale for modifying governance/infrastructure files. Human approval is always required for protected-path changes, regardless of context.

Low

  • [edge-case] .github/scripts/redact-behaviour-artifacts.sh:65 — The _redact_literal_token function passes secret values to awk via -v token="***". The awk -v flag interprets C-style backslash escape sequences (e.g., \n becomes a newline). If any secret value contains a literal backslash followed by an awk-recognized escape character, the token passed to awk will differ from the actual secret, causing redaction to silently miss occurrences. Current secrets (PEM base64, GitHub PATs, UUIDs) do not contain backslashes, so this cannot be triggered today.
    Remediation: Use awk's ENVIRON mechanism instead of -v to pass the token without escape processing.

  • [GHA-workflow-command-injection] .github/scripts/redact-behaviour-artifacts.sh:153_sanitize_log_path strips literal newlines and :: sequences from file paths before they are interpolated into ::warning:: workflow commands, but does not strip %0A/%0D URL-encoded newlines that GitHub Actions interprets as line terminators. An attacker who controls filenames could inject annotation-class workflow commands. Impact is limited: only annotation commands can be injected (not set-env or set-output), and the job has minimal permissions.
    Remediation: Extend _sanitize_log_path to also strip %0A, %0D, %25, carriage returns, and ANSI escape sequences.

  • [edge-case] .github/scripts/redact-behaviour-artifacts.sh:125_redact_text_content and _redact_text_file strip trailing newlines from files during redaction. The $(<file) command substitution drops trailing newlines, and printf '%s' does not restore them. This is cosmetic and does not affect security.

Previous run (2)

Review

Findings

Medium

  • [error-handling] .github/workflows/e2e.yml — If the base-branch checkout or redaction script step fails (e.g., base branch lacks the script on first merge, network error, script bug), the upload step still runs because its failure() condition remains true from the behaviour test failure. This means unredacted artifacts containing secrets could be uploaded when the redaction mechanism itself fails — a silent failure that undermines the PR's security guarantee.
    Remediation: Give the redaction step an id (e.g., id: redact) and condition the upload on steps.redact.outcome != 'failure', or have the redaction step delete the artifact directory on failure so there is nothing to upload.

  • [commit-prefix] PR title uses fix(#5221): but this is a CI/infrastructure security hardening change, not a user-visible bug fix. COMMITS.md explicitly forbids fix(ci) and fix(e2e) because CI changes are not user-visible bug fixes — the same reasoning applies here. Using fix causes this to appear in the "Bug Fixes" section of release notes.
    Remediation: Change the PR title to ci(#5221): redact behaviour debug artifacts before upload.

  • [protected-path] .github/scripts/redact-behaviour-artifacts-test.sh, .github/scripts/redact-behaviour-artifacts.sh, .github/workflows/e2e.yml — This PR modifies files under protected paths (.github/). The PR links to issue e2e: behaviour debug artifacts can exfiltrate secrets without redaction #5221 and explains the rationale for modifying governance/infrastructure files. Human approval is always required for protected-path changes, regardless of context.

Low

  • [edge-case] .github/scripts/redact-behaviour-artifacts.sh:87 — The _redact_patterns regex gh[pousr]_ does not cover ghi_ (GitHub App installation tokens). Risk is low since installation tokens are short-lived and not passed as env vars to the behaviour test step, but expanding to gh[a-z]_ would future-proof the pattern.

  • [test-inadequate] .github/scripts/redact-behaviour-artifacts-test.sh — No test case for tar.gz archive handling. The gzip and zip paths are covered, but _redact_tar_gz_file has its own distinct extraction/re-packing logic (tar -xzf / tar -czf) that is not exercised.

  • [GHA-workflow-command-injection] .github/scripts/redact-behaviour-artifacts.sh:195_stub_opaque_file interpolates ${file} into echo "::warning::..." without sanitizing newlines or :: sequences. PR-head code controls filenames in the artifact directory. Exploitable impact is limited since dangerous workflow commands (::set-env::, ::add-path::) are deprecated, but ::add-mask:: injection could obfuscate log output.

  • [edge-case] .github/scripts/redact-behaviour-artifacts.sh:275_contains_nul_bytes reads only the first 8192 bytes. Files with NUL bytes beyond that offset are classified as text; sed/awk may produce garbled output on the binary-containing lines (redaction of text portions still works).

  • [naming-convention] .github/scripts/redact-behaviour-artifacts.sh — Underscore-prefixed function names (_redact_multiline_pem, _file_kind, etc.) are not used in any other shell script in the repository. All existing scripts use unprefixed snake_case.

  • [keyword-convention] .github/scripts/redact-behaviour-artifacts.shreadonly keyword (for ARCHIVE_PER_FILE_LIMIT and ARCHIVE_TOTAL_LIMIT) is not used in any other shell script in the repository.

  • [environment-hygiene] .github/scripts/redact-behaviour-artifacts.sh_redact_literal_token uses export REDACT_LITERAL_TOKEN=... to pass secrets to awk via ENVIRON. Plain assignment (without export) would suffice for child-process access and avoid briefly leaking the value to the broader environment.


Labels: PR modifies CI workflows (.github/workflows/e2e.yml) and adds CI scripts (.github/scripts/), addressing a security issue in e2e behaviour test infrastructure.


Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review fullsend-ai-review Bot added component/ci CI pipelines and checks component/e2e End-to-end tests labels Aug 13, 2026
Use safe Python archive extraction with pre-extract size limits and path
validation, fix GNU sed case-insensitive flag, build test literals at
runtime for secret scanners, gate artifact upload on redaction success,
and expand GitHub token pattern coverage.

Signed-off-by: Barak Korren <bkorren@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@ifireball ifireball changed the title fix(#5221): redact behaviour debug artifacts before upload ci(#5221): redact behaviour debug artifacts before upload Aug 13, 2026
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 13, 2026

Copy link
Copy Markdown

🤖 Review · ⚠️ Cancelled · Started 9:17 AM UTC · Ended 9:26 AM UTC

Commit: 5e704d1 · View workflow run →

…s manifest

CollectVendoredAssets auto-includes .github/scripts/*; enumerateVendoredPaths
must list the new redaction scripts so scaffold tests stay in sync.

Signed-off-by: Barak Korren <bkorren@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 13, 2026

Copy link
Copy Markdown

🤖 Review · ❌ Terminated · Started 9:27 AM UTC · Ended 9:47 AM UTC

Commit: b8b9cf5 · View workflow run →

@codecov

codecov Bot commented Aug 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@fullsend-ai-review
fullsend-ai-review Bot dismissed their stale review August 13, 2026 09:47

Superseded by updated review

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review fullsend-ai-review Bot added the requires-manual-review Review requires human judgment label Aug 13, 2026
@fullsend-ai-review

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 9:27 AM UTC · Completed 9:47 AM UTC

Commit: b8b9cf5 · View workflow run →

…tization

Pass literal secrets to awk via ENVIRON so backslashes are not escaped,
extend _sanitize_log_path for URL-encoded newlines and ANSI sequences,
and add a backslash literal-secret regression test.

Signed-off-by: Barak Korren <bkorren@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

@waynesun09 waynesun09 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Multi-agent review squad pass (3 agents — Claude + Grok — findings cross-verified against source). Posting the unique medium-and-above findings; everything from the earlier qodo/bot round is already fixed or declared out of scope and is not re-raised. 2 critical, 2 high, 12 medium follow as inline comments.

Two notes: (1) the two critical fixes and the E2E_GCP_SERVICE_ACCOUNT env addition touch .github/workflows/e2e.yml — actionable by you as author, but the automated /fs-fix code agent can't edit workflow files, so those need a manual hand. (2) The base-ref script checkout, fail-closed upload gating, and safe archive traversal/size guards are genuinely well done — the findings below are about the execution environment and the redaction internals, not that design.

Comment thread .github/workflows/e2e.yml
Comment thread .github/workflows/e2e.yml Outdated
Comment thread .github/scripts/redact-behaviour-artifacts.sh
Comment thread .github/scripts/redact-behaviour-artifacts.sh Outdated
Comment thread .github/scripts/redact-behaviour-artifacts.sh
Comment thread .github/scripts/redact-behaviour-artifacts.sh
Comment thread .github/scripts/redact-behaviour-artifacts.sh Outdated
Comment thread .github/scripts/redact-behaviour-artifacts.sh Outdated
Comment thread docs/contributing/ci-workflows.md Outdated
Comment thread .github/scripts/redact-behaviour-artifacts-test.sh
…review

Use shell: bash with pipefail for behaviour-test tee, run redaction in a
clean env -i with pinned PATH, harden the redaction script (multiline PEM
lines, symlinks, capped gzip, archive limits, per-file error handling),
add adversarial tests, and document residual scanning limitations.

Signed-off-by: Barak Korren <bkorren@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 13, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 7:14 PM UTC · Completed 7:29 PM UTC

Commit: 280af01 · View workflow run →

@waynesun09 waynesun09 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving after re-review of 280af014. All findings from the earlier multi-agent squad pass are resolved and verified locally.

Verified locally:

  • redact-behaviour-artifacts-test.sh — 19/19 pass (11 original + 8 new adversarial: multi-line PEM body, one-line JSON PEM, top-level symlink, relative ARTIFACT_DIR zip, unreadable file, NUL-byte .log, gzip bomb)
  • shellcheck 0.11.0 — clean on both scripts
  • go test ./internal/scaffold/... — pass (vendor manifest addition consistent with embedded files)

Findings resolved:

  • Criticaltee masking failures fixed via shell: bash (pipefail); redaction now runs under env -i with pinned PATH, unset LD_PRELOAD/BASH_ENV, absolute interpreter — interpreter/PATH hijack closed, residual same-job race documented honestly.
  • High — multi-line PEM literals now redacted line-by-line; symlinks stubbed before upload (_remove_symlinks).
  • Medium — one-line PEM no longer sets sticky in_pem; archive size guards count bytes actually read (matches Go reference); gzip capped decompress; E2E_GCP_SERVICE_ACCOUNT added; O(n²) loop removed; inherit_errexit + stub-on-failure; NUL check moved ahead of extension classification; ARTIFACT_DIR canonicalized to absolute; unreadable files stubbed instead of aborting.
  • Docs — overclaim corrected to "cannot modify the checked-in script contents" + a Residual Limitations section covering the encoding/obfuscation and same-job-race gaps.

Redaction is a defense-in-depth layer, and the residual limitations (content-scan can't catch every encoding; same-job race) are now documented rather than claimed away — reasonable for this change. Nice work.

@fullsend-ai-review fullsend-ai-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the review comment for full details.

Comment thread .github/scripts/redact-behaviour-artifacts.sh
Comment thread .github/scripts/redact-behaviour-artifacts.sh
Match auth header tokens until the next whitespace so base64 characters
like + and / are covered; add regression test.

Signed-off-by: Barak Korren <bkorren@redhat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 13, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 7:36 PM UTC · Completed 8:15 PM UTC

Commit: c4d8de3 · View workflow run →

@ifireball
ifireball added this pull request to the merge queue Aug 13, 2026
Merged via the queue into fullsend-ai:main with commit 730da37 Aug 13, 2026
18 of 19 checks passed
@ifireball
ifireball deleted the fix/5221-redact-behaviour-artifacts branch August 13, 2026 19:58
@fullsend-ai-retro

fullsend-ai-retro Bot commented Aug 13, 2026

Copy link
Copy Markdown

🤖 Finished Retro · ✅ Success · Started 8:01 PM UTC · Completed 8:17 PM UTC

Commit: c4d8de3 · View workflow run →

@fullsend-ai-review

Copy link
Copy Markdown

Review skipped — this PR is already merged.

The /fs-review command only reviews open pull requests.

Posted by fullsend post-review check

@fullsend-ai-retro

Copy link
Copy Markdown

Retro: PR #6167 — Redact behaviour debug artifacts before upload

Workflow shape: Human-authored PR (with Cursor) fixing issue #5221. Triage ran on the issue; 5 review agent runs across the PR lifecycle; no code or fix agent involvement (triage correctly noted the code agent cannot modify .github/workflows/). Merged same day after thorough human review.

Review quality gap — the central finding. The human reviewer (waynesun09) conducted a multi-agent review squad pass (3 agents cross-verified) and posted 2 critical, 2 high, 12 medium findings. The fullsend review bot posted 7 low-severity findings across 3 review passes. The quality gap is dramatic: the human found that the entire redaction feature was dead code (critical: tee masks failures without pipefail) and architecturally bypassable (critical: same-job execution environment is attacker-controlled via GITHUB_PATH/GITHUB_ENV/LD_PRELOAD). The review agent found only cosmetic or leaf-symptom issues.

Notably, the agent's findings were shallow variants of deeper issues the human caught:

  • Agent: "Bearer regex too narrow" → Human: "Encoded secrets bypass content scrubbing entirely"
  • Agent: "NUL check reads only 8KB" → Human: "Extension-based classification bypasses NUL check before it runs"
  • Agent: "awk -v interprets backslash escapes" → Human: "Multi-line PEM values can never match in line-by-line awk"

The human also verified findings empirically (e.g., bash -ec 'false | tee /dev/null; echo $?'0) — a depth of analysis the review agent did not attempt.

Evidence for existing issues

  • fullsend#1086 (expand security sub-agent for adversarial thinking): This PR is strong evidence. Both critical findings required reasoning about an attacker-controlled execution environment — exactly the adversarial thinking gap review agent (backlog): expand security sub-agent to cover threat modeling, OWASP Top 10, and adversarial thinking #1086 describes.
  • fullsend#2933 (flag CI workflow security anti-patterns): The missing pipefail and shell: bash omission are CI workflow anti-patterns. Review agent should flag CI workflow security anti-patterns #2933 currently covers patterns like curl | tar and verbose secret scanners; this PR shows the gap extends to shell-default and step-isolation patterns.
  • agents#282 (verify shell script security controls against bypass vectors): The multi-line PEM bypass, symlink bypass, and NUL-classification bypass are all shell script security control failures the security sub-agent should have caught.
  • agents#535 (escalate security sub-agent depth based on labels): The PR carried component/ci and requires-manual-review labels — signals that should have triggered deeper security analysis.
  • agents#283 (flag security-critical functions lacking adversarial test coverage): The human found that the test suite only covered happy-path cases with no adversarial scenarios — exactly the gap triage agent: streamline 'sufficient' action to LGTM instead of restating everything #283 describes.
  • agents#499 (detect data exposure via artifact patterns): The redaction bypass vectors (encoded secrets, symlinks, binary-in-text-extension) are artifact-based data exposure paths.
  • agents#302 (self-report coverage gaps on large PRs): 865 lines added across 6 files, including a 518-line security-critical shell script. The agent did not flag any coverage limitations.
  • fullsend#5967 (filter pull_request_review events to changes_requested): 34 fullsend.yaml runs fired in a 2-minute window (19:13–19:15 UTC) when the human reviewer's 16 inline comments each triggered a separate pull_request_review event. 21 were cancelled by concurrency queuing. None dispatched downstream work — the routing logic only acts on changes_requested from the review bot, so all 30 pull_request_review runs just ran the routing script and exited.
  • fullsend#5007 (deduplicate inline review comments): The review agent posted the same trailing-newline finding twice (line 149 at 09:47 UTC, line 125 at 19:29 UTC).

Proposal filed

One proposal filed below for a genuinely novel gap: the review agent's security sub-agent does not analyze GitHub Actions step-execution context (shell defaults, env persistence, step ordering) when reviewing CI workflow changes — the category that produced both critical findings on this PR. No existing open issue covers this specific pattern.

Proposals filed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/ci CI pipelines and checks component/e2e End-to-end tests requires-manual-review Review requires human judgment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

e2e: behaviour debug artifacts can exfiltrate secrets without redaction

2 participants