Skip to content

Add Gemfury storage bucket to egress allowlist - #286

Open
sbresin wants to merge 1 commit into
dependabot:mainfrom
sbresin:sbresin/allowlist-gemfury-s3
Open

sbresin wants to merge 1 commit into
dependabot:mainfrom
sbresin:sbresin/allowlist-gemfury-s3

Conversation

@sbresin

@sbresin sbresin commented Oct 1, 2026 •

Copy link
Copy Markdown

Alternative to #287. Only one of the two should be merged. This PR adds the Gemfury bucket to the static defaults (1 line). #287 derives it per job instead, so only jobs that use Gemfury can reach it. I opened both so you can pick the approach that fits your allowlist policy, and I'll close the other one.

What are you trying to accomplish?

Since the egress allowlist started enforcing, every Dependabot update that downloads a package from a Gemfury registry fails. The authenticated registry request succeeds, but the download is blocked:

proxy | GET https://pypi.fury.io:443/<account>/-/ver_xxxxx/<pkg>-16.0.1-py3-none-any.whl
proxy | * authenticating python index request (host: pypi.fury.io)
proxy | 302 https://pypi.fury.io:443/<account>/-/ver_xxxxx/<pkg>-16.0.1-py3-none-any.whl
proxy | GET https://gemfury.s3-accelerate.dualstack.amazonaws.com:443/gems/<id>/<file>?X-Amz-...
proxy | * egress not allowlisted gemfury.s3-accelerate.dualstack.amazonaws.com
proxy | 403 https://gemfury.s3-accelerate.dualstack.amazonaws.com:443/gems/<id>/<file>?X-Amz-...
updater | Handled error whilst updating pyjwt: ... {source: "https://gemfury.s3-accelerate.dualstack.amazonaws.com"}

Every Gemfury registry endpoint 302-redirects package downloads to a short-lived pre-signed URL on one Gemfury-owned S3 bucket, gemfury.s3-accelerate.dualstack.amazonaws.com. I checked this directly against both pypi.fury.io (wheel) and npm.fury.io (tarball): both redirect to that exact host. Older files are sometimes served inline with a 200, which is why the failure shows up per package rather than per registry.

This PR adds the bucket as an exact host under shared_registry_domains, next to the JFrog-owned S3 buckets. It goes there because Gemfury serves several ecosystems from the same backend.

Anything you want to highlight for special attention from reviewers?

Matching form: the entry is an exact host, as the file header requires for shared storage domains:

  • The bucket name gemfury is already registered. S3 bucket names are globally unique, so no label in the entry is attacker-choosable.
  • Child hosts, lookalike buckets and the shared s3-accelerate parent all stay blocked. See the tests below.

Multi-tenancy: the bucket holds all Gemfury accounts' files, with the account in the path. That's the same situation as the JFrog shared regional buckets. Reaching the host on its own gives access to nothing:

  • Objects can only be fetched with a short-lived pre-signed URL, issued by the authenticated registry.
  • Uploads need Gemfury's own credentials.
  • The access logs belong to Gemfury, so the host can't be used to leak data to an account the requester controls.

Ownership evidence:

  • pypi.fury.io and npm.fury.io themselves issue the redirect to this host.
  • The TLS certificate is Amazon's (CN=*.s3-accelerate.amazonaws.com, issuer Amazon RSA 2048 M01).

Compared with #287: #287 adds the bucket per job instead, only for jobs with a *.fury.io credential, via registryRedirectHosts next to the ECR starport bucket. That follows the rule in add-egress-allowlist-domain for multi-tenant hosts more strictly, at the cost of a little code. This PR is the smaller change and follows the JFrog precedent.

How will you know you've accomplished your goal?

Tests in internal/handlers/egress_allowlist_test.go:

  • TestEgressAllowlist_GemfuryS3BucketAllowedButSharedS3Blocked:
    • The bucket is allowed for both pip and npm_and_yarn jobs.
    • Still blocked: a lookalike bucket (gemfuryx.), another tenant on the shared parent (attacker.s3-accelerate.dualstack.amazonaws.com), and path-style access to the bare accelerate endpoint.
  • TestEgressAllowlist_NewEntriesDoNotWidenBeyondExactHosts has a new child probe, evil.gemfury.s3-accelerate.dualstack.amazonaws.com. I checked that it catches a regression: changing the entry to its leading-dot form makes the test fail.

TestEgressDefaults_NoRedundantEntries passes, and so do script/test (-race -shuffle=on -count=2), go vet and gofmt -l.

Checklist

  • I have run the complete test suite to ensure all tests and linters pass.
  • I have thoroughly tested my code changes to ensure they work as expected, including adding additional tests for new functionality.
  • I have written clear and descriptive commit messages.
  • I have provided a detailed description of the changes in the pull request, including the problem it addresses, how it fixes the problem, and any relevant details about the implementation.
  • I have ensured that the code is well-documented and easy to understand.

Gemfury registries (pypi.fury.io, npm.fury.io, ...) 302-redirect package
downloads to pre-signed URLs on gemfury.s3-accelerate.dualstack.amazonaws.com.
The redirect target was blocked, so updates failed after the authenticated
registry request had succeeded.

Add the bucket as an exact host under shared_registry_domains, like the
JFrog-owned S3 buckets, since Gemfury serves several ecosystems.
@sbresin
sbresin marked this pull request as ready for review October 1, 2026 12:51
@sbresin
sbresin requested a review from a team as a code owner October 1, 2026 12:51
Copilot AI balanced review requested due to automatic review settings October 1, 2026 12:51

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

The global entry bypasses tenant isolation for a shared path-based Gemfury endpoint.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Adds Gemfury’s S3 download bucket to the proxy egress allowlist.

Changes:

  • Adds the exact Gemfury bucket hostname.
  • Adds positive and hostname-boundary regression tests.
File Description
internal/​handlers/​egress_allowlist_defaults.yaml Adds the Gemfury storage host.
internal/​handlers/​egress_allowlist_test.go Tests access and exact-host matching.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

- jfrog-prod-use1-shared-virginia-main.s3.amazonaws.com
- jfrog-prod-usw2-shared-oregon-main.s3.amazonaws.com
- jfrog-prod-use1-dedicated-virginia-main.s3.amazonaws.com
- gemfury.s3-accelerate.dualstack.amazonaws.com
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