Wandering Thoughts archives

2023-11-11

Go modules and the domain expiry problem

Every programming language with aspirations of having a usable system for third party packages has some sort of a namespace problem. Today, Tony Arcieri posted something about Rust's package namespace issues, which caused me to think about Go's approach to the problem. The concise summary is that Go outsources the problem to other people by making package names be URLs. Filippo Valsorda noted that this doesn't solve the domain expiration problem, which is true.

The 'domain expiration problem' is that domains (and URLs on domains) go away and get taken over, for example because the domain registration expires (hence the name). Sometimes this happens despite the owner's best intentions; for example, a lot of .ga domains got removed earlier this year. In the Go context, this means that if you published a module with the official name of, for example, 'fred.ga/go/mypackage', and fred.ga goes away, you're now stuck and there's no good way to recover. Similar issues happen if you publish on a forge and your account goes away, gets banned, or whatever.

(Go has the 'go-meta' HTML <meta> tag to let you publish one URL but have the source actually retrieved from another URL, but this only pushes the problem back one level. You can survive a forge account problem (or just change which forge you like) because you can just change where the go-meta points, but you're still in a pickle if you lose control over the URL where you have the go-meta tag.)

The good news for the general Go ecology is that any new owner of your package's URL has limited scope for being malicious. The Go module checksum database will keep them from publishing a maliciously altered version of any current release, and in theory they can't publish a new version (with malicious code) and have it automatically picked up by current users, because existing users will stick with the current version until they specifically update (new users of the package are not so lucky). And the Go module proxy will probably keep the old versions available.

(In practice, a lot of projects use more or less automated 'dependabot' updates, so I suspect a malicious update with a tiny version number change would slide right in as long as it didn't break people's tests.)

However, that's where the good news ends because today, there's no good automated way for you to update your package or to get news out about its new name (and it has to have a new name, because names are URLs and you can't use the old URL, ie the old name). You're left to make posts in various places and hope people hear about it. If you can do one last version publication on the old URL somehow you can mark your old name (module) deprecated in go.mod, and someday you may be able to automatically forward people to a different name (ie URL) (via), but both of these require (temporary) access to the old URL (including through the cooperation of the new owner).

Let me be clear that this is a hard problem in general and no one has a good answer to it, especially since the flipside of being able to update or add notices about modules without control over their URL is that it opens up obvious possibilities for external stealing or compromise of modules. If I can somehow get the Go module proxy to put up so much as a 'this module is obsolete, use this one instead' notice for my module without control over the module's URL, someone else can too.

programming/GoModulesAndDomainExpiry written at 23:44:07; Add Comment


Page tools: See As Normal.
Search:
Login: Password:
Atom Syndication: Recent Pages, Recent Comments.

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.