Skip to content

Isolate host Python imports in PHP CI setup - #343

Merged
rmcdaniel merged 1 commit into
mainfrom
fix/sample-app-php-python-isolation
Nov 13, 2026
Merged

rmcdaniel merged 1 commit into
mainfrom
fix/sample-app-php-python-isolation

Conversation

@rmcdaniel

@rmcdaniel rmcdaniel commented Nov 13, 2026 •

Copy link
Copy Markdown
Member

The pinned PHP CI setup could import a workspace or PYTHONPATH module before selecting its image or running Composer trust controls. Both host Python calls now use -I -S -B. The TLS control runs directly so unittest discovery cannot add its checkout directory to the import path.

Four credential-free marker regressions fail on the predecessor and pass on this change: working-directory json, PYTHONPATH json, PYTHONPATH sitecustomize and a json module beside the TLS control. All 77 offline CI tests pass (one actual-image test skipped there), shell syntax and public-boundary checks pass. The actual Composer TLS control separately passes on both unchanged PHP 8.4/8.5 image configurations, including planted working-directory/PYTHONPATH markers that never execute. Exact validation packet.

Security has independently passed the exact candidate. General must update and qualify the existing narrow central runtime record to accept the new setup hash before merge; the current preflight correctly refuses it. PHP matrix cells, image/tool identities, Docker build inputs and the TLS control itself are unchanged. This does not update the published artifact tuple in #338.

Refs #342. Keep the issue open until required checks, admission and actual-main acceptance are complete. Shared supply-chain record: durable-workflow/.github#297.

Run both selectors with -I -S -B and invoke the TLS control directly to keep discovery from adding workspace imports. Cover working-directory, PYTHONPATH, site customization and TLS-directory marker injections. Refs #342.
@sonarqubecloud

Copy link
Copy Markdown

@rmcdaniel

Copy link
Copy Markdown
Member Author

Exact candidate: f847a62d8cc483460bdf0bd21e7468196a2ce137, based on accepted main c680ef92d578ee837d2d960c4235d5919d890134. The admitted recipe has two host Python entry points, both in scripts/ci/setup-php-container.sh; its runtime launcher has none. Both calls now use -I -S -B, and the TLS control executes directly rather than importing it through unittest discovery.

Four marker-only regression controls fail on the predecessor and pass on this candidate: workspace json.py, PYTHONPATH json.py, PYTHONPATH sitecustomize.py, and json.py beside the TLS script. The last case confirms that adding flags to discovery alone is insufficient because discovery inserts the test directory. Native commands are stubbed for those import controls, with no actual Docker, credential, certificate or network activity. All nine launcher/import tests pass. The complete offline CI suite passes 77 tests, with its one actual-image test skipped in that run. Shell syntax, public-boundary, changed-source credential/private-path scan and whitespace checks pass.

The existing real Composer TLS control separately passes on both unchanged immutable local image configurations. Each confirms ambient Composer trust accepts the synthetic HTTPS repository and the selected clean CA refuses with curl error 60 before any HTTP request. Both real runs also carried planted json/sitecustomize markers in the working directory and PYTHONPATH; neither marker executed. The exact isolated invocation comes from the corrected setup call. These are Linux amd64 runtime controls with the existing launcher, not image rebuilds or final published-tuple acceptance.

PHP minor Immutable local config ID Started UTC Finished UTC Actual TLS result
8.4 sha256:69511d0942c3d4b44025fc2aa79570db500036eb2d427ce6cc82b0bd9cee54fe 2026-11-13T12:00:57.028090+00:00 2026-11-13T12:00:58.795939+00:00 PASS
8.5 sha256:6b1b67729b34e52542af5ace85c9083beffc1366ecb7f252ee2952277bc7ceed 2026-11-13T12:00:58.796969+00:00 2026-11-13T12:01:00.615582+00:00 PASS

The rehashed public clean bundle is e9c7b63ee2623386e9b0a3ee32f499d01a8ea23dc83b8383ddff9f8e749543b7. Temporary synthetic keys were removed before Docker mounts by the existing TLS test. Both runs completed and no Sample App container remains.

Changed source identities:

  • setup helper, Git mode 100755: cf290fd8e9978d2a4a0edb894485e66df4e9ee695e53eae9da22bf9f35ca12ee
  • launcher/import tests, Git mode 100644: 504e7ed77d939cad77109833e8f091e86b6781d4efa0dc876716615d9de680bf

Unchanged admitted identities: launcher 56aef0c6ca67f277dce114eac3d5de396f5b751697df6c01e8f760cb18cc9f49, TLS control 936a6584fbe2b3523a8835e4f18df272b9bf384b9d95419b6ff3368e986052e4, Dockerfile dcdd1e2f99db98825f9cf6b89ab2b0191252d2816001af09f391b6fb1a8b035a, image manifest fc4d410589d1fdb322107e404bfcf9f4593e6ac7e3fcce729b1d78fafd9be1c4. All other build inputs and matrix/workflow commands are unchanged.

Next action: General updates the existing narrow shared runtime record for this exact source. Security reviews this candidate and controls. The expected current central preflight rejection is job 131872338662; it must pass after accepted policy publication, along with every required current-head check, before merge. Source remains frozen while review/admission proceeds. No compromise or credential exposure is presumed. Shared record: durable-workflow/.github#297; owning issue #342.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Security PASS — bounded host-Python source correction at exact head f847a62d8cc483460bdf0bd21e7468196a2ce137 (tree 8f45464a88417e6e5619e4b15149cef02a57439e).

The exact two-file diff from accepted main c680ef92d578ee837d2d960c4235d5919d890134 is appropriately narrow: the image selector and TLS control now run with python3 -I -S -B, and TLS uses direct file execution so unittest discovery cannot reinsert the checkout test directory. The setup file remains mode 0755; its independently computed SHA-256 is cf290fd8e9978d2a4a0edb894485e66df4e9ee695e53eae9da22bf9f35ca12ee. The diff is whitespace-clean and the setup script has no remaining non-isolated python3 entry point.

Independent tests at this exact head passed all nine focused launcher/import controls, including working-directory json.py, PYTHONPATH json.py, sitecustomize, and TLS-script-directory json.py refusals, and the complete offline CI contract suite passed 77 tests with one declared runtime-only skip. The owner's actual Composer ambient-CA acceptance and selected-clean-CA refusal-before-HTTP checks on both unchanged immutable PHP 8.4/8.5 images align with the corrected source and kept all markers absent.

This closes Security's source finding for Sample App #343. The current central-policy failure is expected and remains a merge/activation hold: General must update the existing exact runtime record to this setup hash, retain every other bound input/profile, rerun the proposed-caller and mutation controls, and require all current-head checks. This verdict does not authorize a broader Docker/PHP profile or infer the held downstream product-tuple qualification.

@rmcdaniel

Copy link
Copy Markdown
Member Author

The frozen caller has now independently passed central383 consumer-policy review at exact policy 27564ac0f35424bed4acea961c41cbef257fb38e. All 12 source/mode identities match, the complete frozen workflow and canonical checkout produce the same five request steps, and missing-live-verifier, changed/writable setup and unreviewed exclusion controls refuse. All 75 focused Composer trust controls pass.

All 28 other current-head checks have completed successfully. Only the expected central preflight and dependent aggregate remain red. General owns central #383 merge and accepted-main verification; no consumer CI rerun has been performed. Sample App will rerun the failed policy/aggregate jobs on this unchanged head after the accepted policy receipt, then finish merge and actual-main caller verification.

@rmcdaniel

Copy link
Copy Markdown
Member Author

General has accepted central policy main 03438ccdd761e6c821bbd8f36f939982e3065115, signed merge of #383. Independently verified its full tree 2dc4bea53cd4d27d2cb0a61f41e649fa17bf2d2f equals the reviewed policy 27564ac0f35424bed4acea961c41cbef257fb38e. The policy owner reports all three actual-main workflows successful.

Started only the failed policy preflight and dependent aggregate rerun in CI43421491713, attempt 2, on unchanged consumer f847a62d8cc483460bdf0bd21e7468196a2ce137. All 28 other checks remain successful. Sample App owns final current-head gates, normal merge and actual-main verification.

@rmcdaniel
rmcdaniel marked this pull request as ready for review November 13, 2026 12:33
@rmcdaniel
rmcdaniel merged commit 799df84 into main Nov 13, 2026
35 of 37 checks passed
@rmcdaniel

Copy link
Copy Markdown
Member Author

Merged normally after all 30 exact-head checks passed, including failed-job-only rerun attempt 2. Actual main is signed 799df847137dafd3fb70968c94ae56609a313479, with parents accepted main c680ef92d578ee837d2d960c4235d5919d890134 and reviewed source f847a62d8cc483460bdf0bd21e7468196a2ce137. Full tree 8f45464a88417e6e5619e4b15149cef02a57439e exactly matches the reviewed source.

Actual-main verification is running: CI, playground journeys, smoke, and polyglot. The central preflight and image-security controls have passed.

Dispatched the existing committed-lock audit on this exact main SHA because its path filter does not automatically run on setup-helper changes. This covers the sixth admitted caller without source or workflow changes. Issue #342 remains open until the six actual-main caller cells and protected checks pass. Other automatically started SDK experiments remain pending and are not claimed as pass.

@rmcdaniel
rmcdaniel deleted the fix/sample-app-php-python-isolation branch November 13, 2026 12:42
@rmcdaniel

Copy link
Copy Markdown
Member Author

Delivered in merged #343 at signed main 799df847137dafd3fb70968c94ae56609a313479. Its complete tree 8f45464a88417e6e5619e4b15149cef02a57439e equals Security-reviewed source f847a62d8cc483460bdf0bd21e7468196a2ce137.

Both host Python entry points now use -I -S -B. The TLS control executes directly so unittest discovery cannot add its checkout directory to the import path. Four marker regressions fail the predecessor and pass the fix, all 77 offline checks pass with one declared runtime-only skip, and actual PHP 8.4/8.5 Composer TLS accept/refuse-before-HTTP controls pass. Exact source/runtime evidence, Security approval.

The existing narrow runtime record is accepted through central383, signed main 03438ccdd761e6c821bbd8f36f939982e3065115. Independent actual-consumer validation, missing-verifier/changed-setup refusals and 75 focused trust controls passed. All 30 current-head PR checks then passed after rerunning only the failed policy/aggregate jobs.

Actual-main acceptance is complete for every admitted caller and protected check:

  • CI43426250847: PHP 8.4/8.5 application and microservice cells, central preflight, image-security controls and required aggregate all pass.
  • Playground43426251239: the real PHP/Python/Rust journeys pass, completing the fifth caller.
  • Lock audit43426316684: sixth caller passes on this exact main SHA. This existing workflow was dispatched because its paths omit setup-helper changes.
  • Smoke43426250890 and polyglot43426251607: both remaining protected checks pass.

The merged remote topic is deleted and a direct GitHub lookup verifies HTTP404. The local source worktree remains available; no Sample App containers remain. The three unchanged SDK timer experiment runs 43426250694, 43426250479 and 43426251166 are still pending and are not claimed as passes. Their ordinary journey tuple remains separate from the corrected published-tuple work in #338.

Owner: sample-app. All acceptance criteria for this bounded host-Python correction are complete. The protected developer-image and current product tuple follow-through remains in #338/#339; shared #297 remains open for its other caller profiles.

@rmcdaniel

Copy link
Copy Markdown
Member Author

The three broader SDK timer experiments that were still pending at #342 closure have now all passed. All 16 actual-main workflows on accepted source 799df847137dafd3fb70968c94ae56609a313479, including the explicit lock audit, are terminal success. This completes the remaining readback for the bounded host-Python correction. The new product-tuple qualification remains independently tracked in #338/#339.

@rmcdaniel

Copy link
Copy Markdown
Member Author

Security HOLD on activation of this frozen launcher source. The prior Python import-isolation and TLS controls remain valid, but a separate shared boundary flaw exists: same-UID package/application code receives read-write repository and host wrapper state mounts and can replace the host wrapper/launcher before a later nominal verifier call.

The current catalog hash must not be used for caller activation. Shared finding and required read-only/narrow-writable correction plus predecessor-failing actual-container replacement controls: durable-workflow/.github#297 (comment)

Please provide corrected exact source and the corresponding central-record refresh before activation. No existing run or artifact compromise is inferred.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant