SE-0292 (3rd review): Package Registry Service

The third review of SE-0292: Package Registry Service, begins now and runs through June 8, 2021.

The proposal has been amended to address the feedback from the second review, and is ready for another review.

Reviews are an important part of the Swift evolution process. All review feedback should be either on this forum thread or, if you would like to keep your feedback private, directly to the review manager or direct message in the Swift forums).

What goes into a review of a proposal?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift.

When reviewing a proposal, here are some questions to consider:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Thank you for helping improve the Swift programming language and ecosystem.

Tom Doron
Review Manager

9 Likes

The proposal doesn't include any DELETE endpoints, so presumably it's up to package registries to decide whether deletion is supported? If that's the case, I think the proposal should define the expected registry behavior such as hard delete vs. soft delete, always returning status 410 (see sample response in API spec) etc., and how SwiftPM should treat these error statuses. If deletion is not allowed, the proposal should state that explicitly to establish the durability guarantee.

1 Like

Although specific policies for publishing and unpublishing packages have not yet been decided, this proposal does provide for packages to be made unavailable by the registry, and specifies the expected behavior of the client:

A server SHOULD communicate the unavailability of a package release using a "problem details" object. A client SHOULD consider any releases with an associated problem to be unavailable for the purposes of package resolution.

For the purposes of this proposal, I think this is sufficient. We can hammer out the details about durability guarantees and what's expected of registries in follow-up proposals.

The Registry Service Specification says in 4.4.1. Integrity verification:

A client SHOULD verify the integrity of a downloaded source archive

Can we change this to a MUST or is there a reason this is a SHOULD?

2 Likes

Another comment regarding checksums: The checksum of the source archive is conveyed in a header when downloading the zip. When the zip is at a different location as described in 4.4.2. Download locations, the registry gives up control over the contents of the zip and I’m wondering if the checksum should rather be in the Package release metadata?

2 Likes

For reference, the guidance of RFC 2119 are as follows:

MUST This word, or the terms "REQUIRED" or "SHALL", mean that the definition is an absolute requirement of the specification.

SHOULD This word, or the adjective "RECOMMENDED", mean that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course.

I can imagine reasons why a client may not use the provided integrity checksums. For example, a client may know that a server provides an invalid checksum for a particular release. Or the client may have a different way to verify the contents of the source archive.

I don't feel too strongly about this, and wouldn't object to making this change if it's deemed necessary.

The response from the server sending a 303 should include a Digest and Content-Length header, as it is otherwise an invalid response for that endpoint. We should correct that in the final specification.

As for the package release metadata endpoint, I'm working on a follow-up pitch to explore various options for providing a SBOM for package releases.

That works, too! @tomerd could we make clear that the digest in the 303 response is the authoritative one, not the one at the target?

@rlacroix After giving this more thought, I think we should remove this section about 303 redirection for source archives entirely. Please see this PR comment for some additional context.

@mattt @rlacroix @yim_lee It is critical that the APIs suggested in SE-0292 allows for deploying a proxy (of kind) that sits between the client and the registry serving the package content, without forcing users to make client side configuration changes (which I assume is what you mean by scoped registry assignment).

My high level thinking on how this would work was that such proxy would fully implement SE-0292 APIs but return an HTTP redirects (+relevant headers for security) to the actual registry where the package is hosted.

wdyt?

1 Like

+1, I don't think we should remove the section about 303.

Can you help me understand what the use case for this behavior is? If the ultimate goal of the registry is to download a source archive securely, it seems odd to me that the final step would allow redirecting to an external host. Wouldn't that cut against durability and immutability guarantees?

I don't see anything preventing a registry from transparently proxying content from an external host. The only real change from disallowing 303 redirects would be that hot-linking isn't supported.

Also, for what it's worth, I wasn't able to find any examples of 303 responses with headers other than Location and Retry-After. The IETF specifications don't seem to say anything about responses using headers to describe redirected resources.

as an example, lets say there are two main registries A, B. In this case it would make sense to deploy a proxy / naming-service of kinds - P - which allows users to configure their clients (SwiftPM) to always resolve from P and have P redirect to A or B depending on prior knowledge it has about the location of the requested packages.

similar example is an enterprise registry that wants to redirect some requests from the client (SwiftPM) to the "upstream" registry.

technically it would be allot more efficient for P to redirect instead of transparently proxying content

That's what scoped registries are for. In practice, I don't expect dependencies to be evenly split between competing registries. Instead, the more likely use case is that private packages are hosted on a private
registry, and the client configures particular scopes to resolve through that.

I think an enterprise registry would be much more likely to download sources from the upstream proxy (either on-demand or occasional synchronization) than to redirect to an external source. For example, that's how npm support for GitHub Enterprise Server works.

I think this is a really big issue, and I hope people are paying attention. We spent a lot of time during the second review of this proposal discussing the fact that the design of this service means that it is heavily biased toward GitHub. The only thing that somewhat mitigates that substantial issue in the design is the ability to create a proxying registry that can operate to confederate multiple other registries. I'm not completely happy with that option, but I'll take is as a compromise.

It is critical that there is an ability to create low-bandwidth package registries that can confederate packages from other registries. Mandated support for redirects creates this opportunity.

The ability to redirect to a source registry substantially eliminates issues of high-bandwidth usage, storage cost, cache coherency, and high latency for confederating proxy registries.

2 Likes

That is pushing all of the configuration client side, on the user vs a proxy where the mapping can be centrally managed on the proxy server side.

SE-0292 has been accepted with modification. If you'd like to continue discussing this, please do so in that thread.