Skip to content

Add GitLab OIDC provider support - #5978

Draft
tachyons wants to merge 10 commits into
rubygems:masterfrom
tachyons:feat/trusted_gitlab
Draft

Add GitLab OIDC provider support#5978
tachyons wants to merge 10 commits into
rubygems:masterfrom
tachyons:feat/trusted_gitlab

Conversation

@tachyons

@tachyons tachyons commented Sep 22, 2025

Copy link
Copy Markdown

The changes add GitLab as a new OIDC trusted publisher, allowing gem publishing from GitLab CI/CD pipelines.

Goals:

  • Add GitLab CI as the supported OIDC provider

Non Goals for this iteration

  • Support for self managed instances
  • Attestation support
stages:
  - deploy

variables:
  GEM_HOST_URL: "https://rubygems.org"

publish:
  stage: deploy
  image: ruby:3.2
  id_tokens:
    GITLAB_OIDC_TOKEN:
      aud: https://rubygems.org
  script:
    - gem install bundler
    - bundle install
    - |
      API_TOKEN=$(ruby -rnet/http -rjson -e "
        uri = URI('${GEM_HOST_URL}/api/v1/oidc/trusted_publisher/exchange_token')
        res = Net::HTTP.post(uri, {jwt: ENV['GITLAB_OIDC_TOKEN']}.to_json, {'Content-Type' => 'application/json'})
        data = JSON.parse(res.body)
        if (res.code == '200' || res.code == '201') && data['rubygems_api_key']
          puts data['rubygems_api_key']
        else
          STDERR.puts 'Token exchange failed: ' + res.body; exit 1
        end
      ")
    - gem build my_gem.gemspec
    - mkdir -p ~/.gem
    - |
      cat > ~/.gem/credentials <<EOF
      ---
      :rubygems_api_key: rubygems_api_key
      ${GEM_HOST_URL}: ${API_TOKEN}
      EOF
    - chmod 0600 ~/.gem/credentials
    - gem push *.gem --host ${GEM_HOST_URL}
  only:
    - tags

Screenshots

Screenshot 2026-07-15 at 4 39 23 PM

Prior art

  1. NPM

img

  1. PyPI

pypi

@codecov

codecov Bot commented Jan 29, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 68.10811% with 59 lines in your changes missing coverage. Please review.
✅ Project coverage is 94.02%. Comparing base (2b4f35a) to head (c494cf9).
⚠️ Report is 222 commits behind head on master.

Files with missing lines Patch % Lines
...s/oidc/trusted_publisher/gitlab/table_component.rb 0.00% 23 Missing ⚠️
...ts/oidc/trusted_publisher/gitlab/form_component.rb 0.00% 21 Missing ⚠️
app/models/oidc/trusted_publisher/gitlab.rb 93.67% 5 Missing ⚠️
app/models/oidc/provider.rb 50.00% 3 Missing ⚠️
...lers/oidc/pending_trusted_publishers_controller.rb 75.00% 2 Missing ⚠️
...lers/oidc/rubygem_trusted_publishers_controller.rb 85.71% 2 Missing ⚠️
app/helpers/rubygems_helper.rb 0.00% 1 Missing ⚠️
.../views/oidc/pending_trusted_publishers/new_view.rb 91.66% 1 Missing ⚠️
.../views/oidc/rubygem_trusted_publishers/new_view.rb 93.75% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #5978      +/-   ##
==========================================
- Coverage   97.24%   94.02%   -3.22%     
==========================================
  Files         476      480       +4     
  Lines        9787    10062     +275     
==========================================
- Hits         9517     9461      -56     
- Misses        270      601     +331     

☔ View full report in Codecov by Sentry.
📢 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.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@tachyons
tachyons force-pushed the feat/trusted_gitlab branch from 8e0f612 to a08c235 Compare June 4, 2026 13:46
@tachyons

tachyons commented Jun 4, 2026

Copy link
Copy Markdown
Author

@colby-swandale Hey, I am trying to add trusted publishing support with GitLab CI. I've tested the functionality with ngrok, and it is working fine.

Before adding proper tests and cleaning up the code, could you please check if I am on the right path ? I tried to mimic the GitHub actions implementation as much as possible.

@colby-swandale

Copy link
Copy Markdown
Member

Hey @tachyons apologies, I dropped the ball on following up with you on this one. I'm looking at this now.

@colby-swandale
colby-swandale self-requested a review June 25, 2026 04:40

@colby-swandale colby-swandale left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Reviewing the draft, I noticed it would be great to include API-level GitLab exchange coverage in the tests, as well as a graceful shutdown for the Attestation path.

@brian-penguin

Copy link
Copy Markdown
Contributor

Ah shoot, sorry to complicate your PR but the redesign has left a bunch of conflicts. Are you okay with updating to match the new layout/styles?

@tachyons

Copy link
Copy Markdown
Author

Let me try, hopefully it wouldn't be hard

tachyons added 5 commits July 15, 2026 06:19
The changes add GitLab as a new OIDC trusted publisher, allowing gem
publishing from GitLab CI/CD pipelines.
@tachyons
tachyons force-pushed the feat/trusted_gitlab branch from cc84eff to 3debdea Compare July 15, 2026 00:51
Comment on lines +28 to +29
def set_selected_trusted_publisher_type
@selected_trusted_publisher_type = OIDC::TrustedPublisher.find_by_url_identifier(params[:trusted_publisher_type]) || OIDC::TrustedPublisher::GitHubAction

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

self review: Falling back to Github action by default to reduce path changes

Comment on lines +90 to +91
when OIDC::TrustedPublisher::GitHubAction then prefill_github_action(instance.trusted_publisher)
when OIDC::TrustedPublisher::GitLab then prefill_gitlab(instance.trusted_publisher)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

self review: Pre-fill some information from the repo path

Comment on lines +222 to +223
# path is e.g. /group/project or /group/subgroup/project — drop leading "/"
{ project_path: link.path.delete_prefix("/") }

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

self review: unlike GitHub, GitLab repo path can be deeply nested

@gitlab_jwt = ->(claims = @gitlab_claims, key: @gitlab_pkey) { JSON::JWT.new(claims).sign(key.to_jwk) }

# Based on the sample GitLab OIDC payload
@gitlab_claims = {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@tachyons
tachyons marked this pull request as ready for review July 15, 2026 11:20
@tachyons
tachyons marked this pull request as draft July 15, 2026 16:02
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.

3 participants