Skip to content

Conversation

@jtfmumm
Copy link
Contributor

@jtfmumm jtfmumm commented May 21, 2025

Extends PR #13560 by using the DisplaySafeUrl and new DisplaySafeUrlRef types in the uv-auth crate.

The old tracing_url function in middleware.rs created a string from request URL and credentials. If tracing was enabled, it would also add credentials to that URL and then mask them. In this PR, this function instead creates a DisplaySafeUrl and sets its credentials to be equal to the passed in credentials. This removes special-case masking logic and also ensures that downstream functions take a DisplaySafeUrl instead of a &str. It comes at the cost of one extra clone per request (not including retries) when tracing mode is disabled.

DisplaySafeUrlRef was added to be able to work with reqwest::Request::url() without having to clone. As an alternative, we could have DisplaySafeUrl wrap a Cow, but this would require new lifetime annotations across many points in the codebase. Given that the need to wrap a &Url is currently limited to a few cases in uv_auth, I decided against paying the ergonomic costs. We could also clone the request Url in each case and then wrap it in a DisplaySafeUrl. This would be a simple change and remove the need for DisplaySafeUrlRef, but would require multiple extra clones per request.

Depends on #13560.

@codspeed-hq
Copy link

codspeed-hq bot commented May 21, 2025

CodSpeed Instrumentation Performance Report

Merging #13576 will degrade performances by 10.62%

Comparing jtfm/log-safe-url-uv-auth (71802f4) with jtfm/log-safe-url (28c59bd)

Summary

❌ 1 regressions
✅ 11 untouched benchmarks

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Benchmarks breakdown

Benchmark BASE HEAD Change
wheelname_tag_compatibility[flyte-long-compatible] 1.8 µs 2 µs -10.62%

@jtfmumm jtfmumm force-pushed the jtfm/log-safe-url-uv-auth branch from 5a811eb to 53ce730 Compare May 22, 2025 10:22
@jtfmumm jtfmumm force-pushed the jtfm/log-safe-url-uv-auth branch from 53ce730 to c2aa92d Compare May 22, 2025 10:23
@jtfmumm jtfmumm force-pushed the jtfm/log-safe-url-uv-auth branch from c2aa92d to 6ff0f5c Compare May 26, 2025 18:11
@jtfmumm jtfmumm force-pushed the jtfm/log-safe-url branch 2 times, most recently from 06d5691 to 2e34b8f Compare May 26, 2025 18:45
@jtfmumm jtfmumm force-pushed the jtfm/log-safe-url branch from 2e34b8f to 6182a23 Compare May 26, 2025 20:31
@jtfmumm jtfmumm force-pushed the jtfm/log-safe-url-uv-auth branch from 6ff0f5c to 71802f4 Compare May 26, 2025 21:34
@jtfmumm jtfmumm merged commit d53904e into jtfm/log-safe-url May 26, 2025
101 of 106 checks passed
@jtfmumm jtfmumm deleted the jtfm/log-safe-url-uv-auth branch May 26, 2025 21:43
jtfmumm added a commit that referenced this pull request May 26, 2025
…ault (#13560)

Prior to this PR, there were numerous places where uv would leak
credentials in logs. We had a way to mask credentials by calling methods
or a recently-added `redact_url` function, but this was not secure by
default. There were a number of other types (like `GitUrl`) that would
leak credentials on display.

This PR adds a `DisplaySafeUrl` newtype to prevent leaking credentials
when logging by default. It takes a maximalist approach, replacing the
use of `Url` almost everywhere. This includes when first parsing config
files, when storing URLs in types like `GitUrl`, and also when storing
URLs in types that in practice will never contain credentials (like
`DirectorySourceUrl`). The idea is to make it easy for developers to do
the right thing and for the compiler to support this (and to minimize
ever having to manually convert back and forth). Displaying credentials
now requires an active step. Note that despite this maximalist approach,
the use of the newtype should be zero cost.

One conspicuous place this PR does not use `DisplaySafeUrl` is in the
`uv-auth` crate. That would require new clones since there are calls to
`request.url()` that return a `&Url`. One option would have been to make
`DisplaySafeUrl` wrap a `Cow`, but this would lead to lifetime
annotations all over the codebase. I've created a separate PR based on
this one (#13576) that updates `uv-auth` to use `DisplaySafeUrl` with
one new clone. We can discuss the tradeoffs there.

Most of this PR just replaces `Url` with `DisplaySafeUrl`. The core is
`uv_redacted/lib.rs`, where the newtype is implemented. To make it
easier to review the rest, here are some points of note:

* `DisplaySafeUrl` has a `Display` implementation that masks
credentials. Currently, it will still display the username when there is
both a username and password. If we think is the wrong choice, it can
now be changed in one place.
* `DisplaySafeUrl` has a `remove_credentials()` method and also a
`.to_string_with_credentials()` method. This allows us to use it in a
variety of scenarios.
* `IndexUrl::redacted()` was renamed to
`IndexUrl::removed_credentials()` to make it clearer that we are not
masking.
* We convert from a `DisplaySafeUrl` to a `Url` when calling `reqwest`
methods like `.get()` and `.head()`.
* We convert from a `DisplaySafeUrl` to a `Url` when creating a
`uv_auth::Index`. That is because, as mentioned above, I will be
updating the `uv_auth` crate to use this newtype in a separate PR.
* A number of tests (e.g., in `pip_install.rs`) that formerly used
filters to mask tokens in the test output no longer need those filters
since tokens in URLs are now masked automatically.
* The one place we are still knowingly writing credentials to
`pyproject.toml` is when a URL with credentials is passed to `uv add`
with `--raw`. Since displaying credentials is no longer automatic, I
have added a `to_string_with_credentials()` method to the `Pep508Url`
trait. This is used when `--raw` is passed. Adding it to that trait is a
bit weird, but it's the simplest way to achieve the goal. I'm open to
suggestions on how to improve this, but note that because of the way
we're using generic bounds, it's not as simple as just creating a
separate trait for that method.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants