refactor(fetch_tls): unify client identity configuration - #622
refactor(fetch_tls): unify client identity configuration#622Kateřina Churanová (kate-shine) wants to merge 1 commit into
Conversation
Represent key-material identities and rustls certificate resolvers as one mutually exclusive client-auth state. Builder calls now use predictable last-setter-wins semantics instead of hidden resolver precedence. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR refactors fetch_tls client-identity configuration by unifying in-memory key material (ClientIdentity) and rustls’ ResolvesClientCert into a single internal ClientAuth representation stored in shared TLS options. This makes repeated configuration deterministic (“last builder call wins”) while allowing TlsOptions to be cloned without duplicating private-key material.
Changes:
- Introduces internal
ClientAuth(Identity(Arc<ClientIdentity>)/ rustls-onlyResolver(...)) and stores it inSharedOptions. - Updates rustls backend build/configuration and builder API to read/write
SharedOptions::client_auth(removing the rustls-backend-local resolver state). - Updates native-tls backend to access client identity via a shared accessor, and refreshes tests to validate replacement semantics.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| crates/fetch_tls/src/rustls.rs | Switches rustls client-auth materialization to SharedOptions::client_auth and updates builder/tests for deterministic “last call wins”. |
| crates/fetch_tls/src/options.rs | Adds ClientAuth + client_auth to shared options, storing identities behind Arc and documenting replacement behavior. |
| crates/fetch_tls/src/native_tls.rs | Updates native-tls backend to read the shared client identity via SharedOptions::client_identity() and adjusts tests accordingly. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Codecov Report❌ Patch coverage is
❌ Your project check has failed because the head coverage (99.9%) is below the target coverage (100.0%). You can increase the head coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #622 +/- ##
========================================
- Coverage 100.0% 99.9% -0.1%
========================================
Files 472 472
Lines 45447 45451 +4
========================================
+ Hits 45447 45450 +3
- Misses 0 1 +1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
## Problem Pull requests from forks can never merge. They sit forever on: > Code scanning is waiting for results from CodeQL for the commits `<sha>` or `<sha>`. Current example: #624 (from `sandersaares/oxidizer`). **Root cause:** this repo uses CodeQL **default setup**, and default setup does not run for pull requests from forks — [that exclusion is documented behaviour](https://docs.github.com/en/code-security/concepts/code-scanning/setup-types), not a bug. The code-scanning merge-protection rule still expects a `CodeQL` result, so the check stays pending indefinitely and the PR is permanently blocked. Evidence gathered on this repo: | PR | Head repo | Fork? | CodeQL run | CodeQL check | |----|-----------|-------|-----------|--------------| | #621, #632, #568, #570-#573 | `microsoft/oxidizer` | no | yes | yes | | #624 | `sandersaares/oxidizer` | yes | none | none, blocked | | #622 | `kate-shine/oxidizer` | yes | none | none, blocked | ## Why advanced setup fixes it An advanced-setup workflow triggered by `pull_request` **does** run for fork PRs, and GitHub accepts its SARIF upload on public repositories even though the fork's `GITHUB_TOKEN` is read-only. Verified empirically against `prettier/prettier`, a public repo on advanced setup. On fork PR head `bf2849cee9d467aedf3fbd42a95201ea4393f855` (from `splincode/prettier`): - the only workflow runs are `pull_request` ones, including `.github/workflows/codeql.yml`; there is no `dynamic` (default setup) run at all; - yet `github-advanced-security` posted check `CodeQL` with conclusion `success`. ## History `.github/workflows/codeql.yml` already exists and is correct, but it has been in the `disabled_manually` state since **2026-01-22** and has not run since. It was introduced by #219 ("ci: Switch to advanced CodeQL mode"), whose stated goal was, verbatim, *"Once this is checked in, then we can tweak to improve permissions on forks"* — exactly the problem above. It ran 33 times, all successful, and roughly 4.5 hours after that PR merged, default setup was switched back on in the repository settings, which automatically disabled this workflow. No PR, issue or comment records a reason. Since then #232, #237, #462, #470, #484, #543, #563 and #574 have all been maintaining a workflow that never runs. ## Changes - Document why advanced setup is preferred, so this does not get silently reverted to default setup a second time. - Add the `merge_group` trigger. `main.yml` and `anvil-pr.yml` both have it and `codeql.yml` did not; without it the merge queue stalls on this workflow once it is required. - Bump `github/codeql-action` to `v4.37.3` (confirmed `"immutable": true` via the releases API, consistent with the existing tag-pinning rationale in the file). ## Required admin action, this PR alone is not sufficient Merging this changes nothing by itself, because the workflow is still disabled and GitHub will keep it disabled while default setup is on. A repository admin must, **in this order**: 1. Settings, Advanced Security, **disable CodeQL default setup**. 2. Re-enable this workflow: `gh api -X PUT repos/microsoft/oxidizer/actions/workflows/codeql.yml/enable`. Doing step 2 first does not work. ## Trade-off Fork PRs from **first-time contributors** will show CodeQL as `action_required` until a maintainer clicks "Approve and run". That is standard GitHub Actions fork policy and it also applies to every other `pull_request` workflow in this repo today. It is a single click, versus the current situation where fork PRs cannot merge at all. ## Draft Left as a draft until an admin confirms they will make the settings change, since merging without it is a no-op. Co-authored-by: Kateřina Churanová <katerina.churanova@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Summary
ClientAuthstateclient_identityand rustls-specificclient_identity_resolverAPIsArcso cloning TLS options does not duplicate private-key bytesValidation
fetch_tlsformatting