Skip to content

Add API to configure pending trusted publishers - #6637

Open
segiddins wants to merge 4 commits into
rubygems:masterfrom
segiddins:api-pending-trusted-publishers
Open

Add API to configure pending trusted publishers#6637
segiddins wants to merge 4 commits into
rubygems:masterfrom
segiddins:api-pending-trusted-publishers

Conversation

@segiddins

Copy link
Copy Markdown
Contributor

Adds a JSON API to create and list pending trusted publishers (OIDC::PendingTrustedPublisher), so trusted publishing can be configured for a gem that has not been pushed yet.

Until now OIDC::PendingTrustedPublisher was only reachable through the website. The configure_trusted_publisher CLI configures publishers via api/v1/gems/:name/trusted_publishers, which 404s when the gem does not exist — exactly the case where a maintainer wants keyless publishing set up before the first release.

What this adds

  • GET/POST api/v1/oidc/pending_trusted_publishers via Api::V1::OIDC::PendingTrustedPublishersController (index + create), modeled on the existing Api::V1::OIDC::RubygemTrustedPublishersController.
  • Api::OIDC::PendingTrustedPublisherPolicy with a user-scoped Scope.
  • Request body mirrors the rubygem endpoint: { rubygem_name, trusted_publisher_type, trusted_publisher: { ... } }.
  • The model now serializes a nested trusted_publisher (via payload/as_json, mirroring OIDC::RubygemTrustedPublisher) so API consumers get the same shape as the rubygem endpoint.

Authorization

  • Requires a user API key with the configure_trusted_publishers scope; create also enforces MFA/OTP.
  • Gem-scoped keys are denied: pending publishers are for not-yet-existing gems, so a gem-restricted key has no meaningful gem to bind to and must not register arbitrary names. (ApiKey#scope? does not reject a gem-scoped key when called with a nil gem, so this guard is load-bearing.)
  • The existing available_rubygem_name validation still rejects reserved names and names of existing pushable gems.
  • index returns only the calling user's unexpired pending publishers.

Tests

Integration tests cover create success and the nested-serialization contract, unsupported type / invalid attributes / unavailable name (422), missing scope / gem-scoped key / non-user key (403), missing OTP under MFA (401), and index isolation between users.

Companion change

The rubygems/configure_trusted_publisher CLI is updated to fall back to this endpoint when the gem does not exist (separate PR in that repo).

@codecov

codecov Bot commented Jun 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.56098% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 94.66%. Comparing base (b12e1a9) to head (e1df4ee).

Files with missing lines Patch % Lines
...icies/api/oidc/pending_trusted_publisher_policy.rb 93.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #6637      +/-   ##
==========================================
- Coverage   97.14%   94.66%   -2.48%     
==========================================
  Files         516      518       +2     
  Lines       11022    11122     +100     
==========================================
- Hits        10707    10529     -178     
- Misses        315      593     +278     

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

@colby-swandale
colby-swandale self-requested a review June 23, 2026 06: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.

Looks good! One minor thing and this is good to merge

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