Repository: astral-sh/uv
File: crates/uv-publish/src/trusted_publishing.rs (Rust)

Code before:
    client: &ClientWithMiddleware,
) -> Result<TrustedPublishingToken, TrustedPublishingError> {
    // GitHub Actions flow
    if let (Ok(_), Ok(oidc_token_request_token)) = (
        env::var(EnvVars::GITHUB_ACTIONS),
        env::var(EnvVars::ACTIONS_ID_TOKEN_REQUEST_TOKEN),
    ) {
        // Request 1: Get the audience
        let audience = get_audience(registry, client).await?;
        // Request 2: Get the OIDC token from GitHub.
        let oidc_token = get_oidc_token(&audience, &oidc_token_request_token, client).await?;
        // Request 3: Get the publishing token from PyPI.
        let publish_token = get_publish_token(registry, &oidc_token, client).await?;
        debug!("Received token, using trusted publishing via GitHub Actions");
        // Tell GitHub Actions to mask the token in any console logs.
        #[allow(clippy::print_stdout)]
        if env::var(EnvVars::GITHUB_ACTIONS) == Ok("true".to_string()) {
            println!("::add-mask::{}", &publish_token);
        }
        return Ok(publish_token);
    }

    // GitLab CI flow: discover OIDC token via {AUD}_ID_TOKEN (PYPI_ID_TOKEN, TESTPYPI_ID_TOKEN)
    if env::var(EnvVars::GITLAB_CI).is_ok() {
        let audience = get_audience(registry, client).await?;
        let env_key = format!("{}_ID_TOKEN", audience.to_ascii_uppercase());
        if let Ok(jwt) = env::var(&env_key) {
            let publish_token = get_publish_token(registry, &jwt, client).await?;
            debug!("Received token, using trusted publishing via GitLab (audience: {audience})");
            return Ok(publish_token);
        }
    }

    // If we get here, we couldn't obtain a token via any known mechanism.
    // For GitHub, surface the clearer missing-variable error.
    let err = env::var(EnvVars::ACTIONS_ID_TOKEN_REQUEST_TOKEN)
        .map(|_| String::new())
        .err()
        .map(|e| TrustedPublishingError::from_var_err(EnvVars::ACTIONS_ID_TOKEN_REQUEST_TOKEN, e));
    if let Some(err) = err {
        return Err(err);
    }
    // For GitLab CI, indicate the expected variables.
    if env::var(EnvVars::GITLAB_CI).is_ok() {
        return Err(TrustedPublishingError::MissingEnvVar(
            "PYPI_ID_TOKEN/TESTPYPI_ID_TOKEN",
        ));
    }
    // Otherwise, indicate that the OIDC token is missing for the environment.
    Err(TrustedPublishingError::MissingEnvVar(
        EnvVars::ACTIONS_ID_TOKEN_REQUEST_TOKEN,

Review comment (suggestion):
This probably needs to be normalized, i.e. so that `aud: foo-bar` doesn't become `FOO-BAR_ID_TOKEN`.

Here's the relevant transform from `id`:

https://github.com/di/id/blob/48252f62c5a3d7bf16432466ae6fa78d7923639f/id/_internal/oidc/ambient.py#L295

Code after:
    // Perform ambient OIDC token discovery.
    // Depending on the host (GitHub Actions, GitLab CI, etc.)
    // this may perform additional network requests.
    let oidc_token = get_oidc_token(&audience, client).await?;

    // Exchange the OIDC token for a short-lived upload token,
    // if OIDC token discovery succeeded.
    if let Some(oidc_token) = oidc_token {
        let publish_token = get_publish_token(registry, oidc_token, client).await?;

        // If we're on GitHub Actions, mask the exchanged token in logs.
        #[allow(clippy::print_stdout)]
        if env::var(EnvVars::GITHUB_ACTIONS) == Ok("true".to_string()) {
            println!("::add-mask::{publish_token}");
        }

        Ok(Some(publish_token))
    } else {
        // Not in a supported CI environment for trusted publishing.
        Ok(None)
    }
}

async fn get_audience(
    registry: &DisplaySafeUrl,
    client: &ClientWithMiddleware,
) -> Result<String, TrustedPublishingError> {
    // `pypa/gh-action-pypi-publish` uses `netloc` (RFC 1808), which is deprecated for authority
    // (RFC 3986).
    // Prefer HTTPS for OIDC discovery; allow HTTP only in test builds
    let scheme: &str = if cfg!(feature = "test") {
        registry.scheme()
    } else {
        "https"
    };
    let audience_url = DisplaySafeUrl::parse(&format!(
        "{}://{}/_/oidc/audience",
        scheme,
        registry.authority()
    ))?;
    debug!("Querying the trusted publishing audience from {audience_url}");
    let response = client
        .get(Url::from(audience_url.clone()))
        .send()
        .await
        .map_err(|err| TrustedPublishingError::ReqwestMiddleware(audience_url.clone(), err))?;
    let audience = response
        .error_for_status()
        .map_err(|err| TrustedPublishingError::Reqwest(audience_url.clone(), err))?
        .json::<Audience>()
        .await