Skip to content

refactor(fetch_tls): unify client identity configuration - #622

Draft
Kateřina Churanová (kate-shine) wants to merge 1 commit into
microsoft:mainfrom
kate-shine:u/kchuranov/unify-mtls-client-auth
Draft

refactor(fetch_tls): unify client identity configuration#622
Kateřina Churanová (kate-shine) wants to merge 1 commit into
microsoft:mainfrom
kate-shine:u/kchuranov/unify-mtls-client-auth

Conversation

@kate-shine

Copy link
Copy Markdown
Contributor

Summary

  • represent key-material identities and rustls client-certificate resolvers with one internal ClientAuth state
  • preserve the portable client_identity and rustls-specific client_identity_resolver APIs
  • make repeated identity configuration predictable: the last builder call wins instead of the resolver silently taking precedence
  • share configured key material through Arc so cloning TLS options does not duplicate private-key bytes

Validation

  • fetch_tls formatting
  • 71 crate tests
  • Clippy across all targets and features with warnings denied
  • API docs with no features and all features
  • generated README and spelling checks

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>
Copilot AI review requested due to automatic review settings July 31, 2026 10:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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-only Resolver(...)) and stores it in SharedOptions.
  • 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

codecov Bot commented Jul 31, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 91.66667% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 99.9%. Comparing base (fa2de0c) to head (d57f0a2).
⚠️ Report is 26 commits behind head on main.

Files with missing lines Patch % Lines
crates/fetch_tls/src/options.rs 83.3% 1 Missing ⚠️

❌ 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     
Flag Coverage Δ
linux ?
linux-arm ?
scheduled ?
windows ?

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Kateřina Churanová (kate-shine) added a commit that referenced this pull request Aug 3, 2026
## 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants