Skip to content

Conversation

@cseeman
Copy link

@cseeman cseeman commented Jan 7, 2026

Hey there RubyGems and @jenshenny 👋 Long time listener, first time caller.

This change addresses issue #4294 by adding optional fields to specify a different repository for the workflow source when using GitHub Actions reusable workflows.

When a repository calls a reusable workflow from a different repository, the OIDC token's job_workflow_ref claim points to the reusable workflow's location, not the caller's workflow. Previously, RubyGems trusted publishing only supported workflows defined in the same repository as the caller.

Security Model Note:

The implementation preserves security by continuing to validate the repository claim (the caller repository) against repository_owner/repository_name. This ensures:

  • Only explicitly authorized repositories can publish to a gem
  • Sharing a workflow does not grant publishing access
  • An attacker using the same shared workflow from an unauthorized repo will be rejected

Example configuration for a gem using a shared release workflow:

- repository_owner: "my-org" (the gem's repo
- repository_name: my-gem
- workflow_filename: shared-release.yml
- workflow_repository_owner: shared-org (the shared workflow's repo)
- workflow_repository_name: shared-workflows

I am starting to use a shared release workflow file with RubyGems Trusted Publishing on the organization gems and it would be amazing to get this working, so I thought I would take a go at adding this feature to RubyGems. Happy address any feedback or requested changes on this, and let me know if anything isn't up to your contributing guide.

@codecov
Copy link

codecov bot commented Jan 8, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.51%. Comparing base (d05f69e) to head (ff8e457).
⚠️ Report is 9 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #6184      +/-   ##
==========================================
- Coverage   97.24%   94.51%   -2.74%     
==========================================
  Files         476      476              
  Lines        9788     9875      +87     
==========================================
- Hits         9518     9333     -185     
- Misses        270      542     +272     

☔ 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.

@cseeman cseeman force-pushed the feature/reusable-workflow-trusted-publishing branch 3 times, most recently from 71eacf0 to 9ca749a Compare January 8, 2026 22:34
Copy link
Member

@jenshenny jenshenny left a comment

Choose a reason for hiding this comment

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

Hi @cseeman!! Thanks for putting up a PR for this ❤️

Comment on lines +38 to +45
same_repo = workflow_repo_owner == repository_owner && workflow_repo_name == repository_name
base = if same_repo
base.where(workflow_repository_owner: workflow_repo_owner, workflow_repository_name: workflow_repo_name)
.or(base.where(workflow_repository_owner: nil, workflow_repository_name: nil))
else
base.where(workflow_repository_owner: workflow_repo_owner, workflow_repository_name: workflow_repo_name)
end
Copy link
Member

Choose a reason for hiding this comment

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

I'm considering that after this is shipped, maybe instead of the columns being optional, we make it required and backfill values to match the org and repo names. That way here, instead of also checking for nil values, we can solely query for the workflow_repo_ownerand workflow_repository_name.

Copy link
Author

Choose a reason for hiding this comment

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

I think that would be great. All the for_claims stuff would become more simple. Also simpler queries - No .or() clause needed, single path through for_claims, simpler validation, just remove workflow_repository_fields_consistency and workflow_repository_differs_from_repository entirely. And you would have more explicit data, every record clearly states where its workflow lives, no implicit "nil means same repo". I am definitely for that.

@cseeman cseeman force-pushed the feature/reusable-workflow-trusted-publishing branch 3 times, most recently from 9bebbc6 to f1dd0af Compare January 9, 2026 21:32
This change addresses issue rubygems#4294 by adding optional fields to specify
a different repository for the workflow source when using GitHub Actions
reusable workflows.

When a repository calls a reusable workflow from a different repository,
the OIDC token's `job_workflow_ref` claim points to the reusable workflow's
location, not the caller's workflow. Previously, RubyGems trusted publishing
only supported workflows defined in the same repository as the caller.

Security: Still validates caller repository against repository_owner/name,
preventing unauthorized repositories from publishing via shared workflows

Example configuration for a gem using a shared release workflow:
- repository_owner: "my-org" (the gem's repo
- repository_name: my-gem
- workflow_filename: shared-release.yml
- workflow_repository_owner: shared-org (the shared workflow's repo)
- workflow_repository_name: shared-workflows
@cseeman cseeman force-pushed the feature/reusable-workflow-trusted-publishing branch from f1dd0af to ff8e457 Compare January 12, 2026 16:21
Copy link
Member

@jenshenny jenshenny left a comment

Choose a reason for hiding this comment

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

This looks good to me. I'll leave this open for a bit so @colby-swandale has a chance to look. When merged, I'll test this on staging to see if everything works as expected before it's shipped to prod.

In the meantime, would you be willing to open a PR to update the trusting publishing guides with the added fields? https://github.com/rubygems/guides

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

2 participants