Skip to content

Disable APT retries before setup-php in CI and Sonar - #373

Merged
rmcdaniel merged 3 commits into
mainfrom
general/295b-apt-no-retries
Nov 13, 2026
Merged

rmcdaniel merged 3 commits into
mainfrom
general/295b-apt-no-retries

Conversation

@rmcdaniel

Copy link
Copy Markdown
Member

Part of #295 (CVE-2026-109518: APT follows a redirect on retry, then installs a swapped package as root).

ci.yml (contracts) and sonar.yml (analysis) run shivammathur/setup-php on ubuntu-latest. setup-php can call apt-get itself: its package-repair, extension and packaged-PHP paths do. Hosted runner images aren't pinned, so the runner's apt version can't be checked ahead of time.

Change

  • Both jobs write Acquire::Retries "0"; to /etc/apt/apt.conf.d/99-no-retries before setup-php. Same pattern as cli#121 and waterline#300. The step sits after bootstrap-patched-pip and before setup-php, so the Composer-trust order is unchanged.
  • Needs Security's exact-source review: scripts/protected_policy_context.py gets a new REVIEWED_APT_NO_RETRIES_SOURCE_CI_SUCCESSORS entry. It holds the new exact SHA-256 of each workflow: ci.yml 760de748…31719fc, sonar.yml f7fad836…55038ed9c749fdfcd86e1312bfca3cced. Both workflows are reviewed complex workflows, so any byte change needs a registered identity. The earlier identities stay registered.
  • New tests/test_apt_no_retries.py, collected by tests.test_ci_trust, so neither workflow's unittest module list changes. It fails if any job reaches shivammathur/setup-php or a networked APT step before that line. It also has a control for a late or missing line.

Unchanged:

  • qualify-linux-php-initial.yml and qualify-linux-php-ubuntu24.yml use the local bound setup-php-linux. Its derived runtime removes or refuses setup-php's APT paths (scripts/php_linux_recipe.py GUARDS, php_linux_bootstrap.installer_source).
  • qualification/vendor/setup-php-f3e473d/*.sh are reference bytes that are compared, never executed.

Local results

  • The workflow's unittest list: 815 tests. The only failure is test_pip_cert_alone_is_additive_but_exported_file_and_empty_directory_refuse, which fails the same way on unmodified main here.
  • check_public_boundary.py passes.
  • qualification_policy.py validate --target github-control-plane passes.

🤖 Generated with Claude Code

Shared contract tests (ci.yml) and Sonar analysis (sonar.yml) run
shivammathur/setup-php on unpinned hosted runners, and setup-php can run
apt-get itself. Write Acquire::Retries "0" before setup-php in both, so
the retry-after-redirect precondition of CVE-2026-109518 is absent (as in
cli#121 and waterline#300).

Both workflows are complex reviewed workflows, so register their exact new
byte identities in protected_policy_context.py. Add test_apt_no_retries
(collected by test_ci_trust) so every APT-capable job keeps the line
first. The bound setup-php-linux workflows refuse setup-php's APT paths
and are unchanged.

Refs #295

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@rmcdaniel rmcdaniel added the agent:general Pull request opened by General agent label Nov 13, 2026
@rmcdaniel

Copy link
Copy Markdown
Member Author

Depends on #374. Validate native policy subject fails here as expected: it checks this PR's ci.yml/sonar.yml bytes against main's protected_policy_context.py registry, which doesn't have them yet. #374 registers exactly these bytes (760de748…, f7fad836…) and nothing else. After #374 merges, rebase this PR so the registry hunk drops out, then re-run the check.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Security PASS at 617778f, conditional on the branch update after #374. Each workflow gains one step, echo 'Acquire::Retries "0";' | sudo tee /etc/apt/apt.conf.d/99-no-retries, right before the pinned setup-php, and nothing else changes. tests/test_apt_no_retries.py guards it. The bytes equal the hashes registered in #374, which accounts for the expected 'Validate native policy subject' failure until #374 merges. After the update, the diff should contain only the two workflows and the tests. If anything else changes, send it back to me.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Security: confirmed at db27d1c. Its parents are 617778f and main 114ad7d (the #374 merge), and nothing changed relative to 617778f. The PR's diff against main is only ci.yml, sonar.yml and the two test files. The workflow bytes (760de748… / f7fad836…) equal the hashes #374 registered. My PASS holds at this head, conditional on green CI.

@sonarqubecloud

Copy link
Copy Markdown

@rmcdaniel
rmcdaniel merged commit 0957846 into main Nov 13, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent:general Pull request opened by General agent

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant