Skip to content

Conversation

Turbo87
Copy link
Member

@Turbo87 Turbo87 commented Oct 2, 2025

This PR adjusts our POST /api/v1/trusted_publishing/tokens endpoint to also accept GitLab OIDC tokens.

As discussed in #11988, we are using a trust-on-first-use principle for the namespace IDs for GitLab due to some API constraints. In other words: the token exchange endpoint will fill in the namespace_id column from the OIDC JWT claims if it was empty before and on each subsequent token exchange it will only accept it if the IDs are matching.

Other than that, this is essentially the same implementation as for GitHub Actions.

Worth noting also is that, just like PyPI, we only support gitlab.com for now, but not any self-hosted GitLab instances.

Related

@Turbo87 Turbo87 added C-enhancement ✨ Category: Adding new behavior or a change to the way an existing feature works A-backend ⚙️ labels Oct 2, 2025
@Turbo87 Turbo87 requested a review from a team October 2, 2025 01:18
@Turbo87 Turbo87 force-pushed the gitlab-oidc-exchange branch from b2d6282 to d2eea95 Compare October 2, 2025 01:52
@Turbo87 Turbo87 force-pushed the gitlab-oidc-exchange branch from d2eea95 to 4449eed Compare October 2, 2025 02:14
Copy link
Contributor

@LawnGnome LawnGnome left a comment

Choose a reason for hiding this comment

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

LGTM!

insert_jti(conn, &signed_claims.jti, signed_claims.exp).await?;

let project_path = &signed_claims.project_path;
let Some((namespace, project)) = project_path.rsplit_once('/') else {
Copy link
Contributor

Choose a reason for hiding this comment

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

I know why this is rsplit_once (the GitLab optional project thing), but it might be worth a comment explaining why this differs from GitHub, since rsplit_once versus split_once is pretty subtle.

Copy link
Member Author

Choose a reason for hiding this comment

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

oh, I thought I had left a comment on that, but apparently not. I'll add one. 👍


if repo_configs.is_empty() {
let message = format!(
"The Trusted Publishing config for repository `{project_path}` does not match the namespace ID ({}) in the JWT. Expected namespace IDs: {}. Please recreate the Trusted Publishing config to update the namespace ID.",
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a really good explanation. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-backend ⚙️ C-enhancement ✨ Category: Adding new behavior or a change to the way an existing feature works
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants